<?php
/**
 * Client-side Audience Settings.
 *
 * Stores the operator's audience selection in WP options, syncs to server
 * via /audience/set. Server is authoritative; client is just cache.
 *
 * @package SwapAds\Client\Audience
 * @since   1.0.0
 */

declare(strict_types=1);

namespace SwapAds\Client\Audience;

use SwapAds\Client\Api\RestClient;
use SwapAds\Client\License\LicenseManager;

/**
 * Class SiteAudience.
 *
 * @since 1.0.0
 */
final class SiteAudience
{
    public const OPTION_NICHE_CODE     = 'swapads_client_audience_niche_code';  // F235: single-niche Y1
    public const OPTION_SUB_NICHES     = 'swapads_client_audience_sub_niches';
    public const OPTION_GEO_BUCKETS    = 'swapads_client_audience_geo_buckets';
    public const OPTION_TRAFFIC_RANGES = 'swapads_client_audience_traffic_ranges';
    public const OPTION_LAST_SYNC      = 'swapads_client_audience_last_sync';

    /**
     * Get audience settings.
     *
     * @return array<string, array<int, string>>
     */
    public static function get(): array
    {
        return [
            'niche_code'     => (string) get_option(self::OPTION_NICHE_CODE, ''),  // F235
            'sub_niches'     => (array) get_option(self::OPTION_SUB_NICHES, []),
            'geo_buckets'    => (array) get_option(self::OPTION_GEO_BUCKETS, []),
            'traffic_ranges' => (array) get_option(self::OPTION_TRAFFIC_RANGES, []),
        ];
    }

    /**
     * Save audience settings locally + push to server.
     *
     * @param array<int, string> $niches
     * @param array<int, string> $subNiches
     * @param array<int, string> $geoBuckets
     * @param array<int, string> $trafficRanges
     *
     * @return array<string, mixed> Server response.
     */
    /**
     * Save audience settings locally + push to server.
     *
     * @since 1.0.0
     * @since 1.5.2 F235: accept $nicheCode (single-niche Y1 selection).
     *                    First param $niches is deprecated (kept for back-compat).
     */
    public static function save(?string $nicheCode, array $subNiches, array $geoBuckets, array $trafficRanges): array
    {
        $nicheCode = ($nicheCode !== null && $nicheCode !== '') ? $nicheCode : null;
        update_option(self::OPTION_NICHE_CODE, $nicheCode);
        update_option(self::OPTION_SUB_NICHES, array_values(array_unique($subNiches)));
        update_option(self::OPTION_GEO_BUCKETS, array_values(array_unique($geoBuckets)));
        update_option(self::OPTION_TRAFFIC_RANGES, array_values(array_unique($trafficRanges)));
        // Push to server only if licensed
        if (!LicenseManager::isLicensed()) {
            update_option(self::OPTION_LAST_SYNC, current_time('mysql'));
            return ['success' => true, 'local_only' => true];
        }
        // Push to server
        $client = RestClient::fromOption();
        $result = $client->post('/wp-json/swapads-server/v1/audience/set', [
            'niche_code'     => $nicheCode,
            'sub_niches'     => $subNiches,
            'geo_buckets'    => $geoBuckets,
            'traffic_ranges' => $trafficRanges,
        ]);
        if (($result['http_status'] ?? 0) === 200) {
            update_option(self::OPTION_LAST_SYNC, current_time('mysql'));
        }
        return $result;
    }

    /**
     * Check if audience has been declared.
     *
     * @return bool
     */
    public static function isDeclared(): bool
    {
        $aud = self::get();
        return !empty($aud['niche_code']) || !empty($aud['sub_niches']);
    }
}
