<?php
if (!defined('ABSPATH')) exit;

// =============================================================================
// GEOLOCALIZAÇÃO DE VISITANTES (partilhada entre tracking e targeting de anúncios)
// =============================================================================

/**
 * Devolve a geolocalização do visitante por IP, com cache em transient.
 *
 * - Sucesso: cache de 12 horas.
 * - Falha (API em baixo / IP privado): cache de 15 minutos com valores vazios,
 *   para não martelar o serviço externo em cada pedido.
 * - Fail-open: quem consome deve tratar country/region vazios como "desconhecido"
 *   e não excluir nada com base nisso.
 *
 * @param  string|null $ip IP a consultar; null = IP do visitante atual.
 * @return array{country: string, region: string} Ex: ['country' => 'MZ', 'region' => 'Maputo City']
 */
function imz_ads_get_visitor_geo(?string $ip = null): array {
    $empty = ['country' => '', 'region' => ''];

    if (is_null($ip)) {
        $ip = function_exists('imz_get_user_ip') ? imz_get_user_ip() : sanitize_text_field($_SERVER['REMOTE_ADDR'] ?? '');
    }
    if (empty($ip) || $ip === '0.0.0.0') {
        return $empty;
    }

    $cache_key = 'imz_geo_' . md5($ip);
    $cached = get_transient($cache_key);
    if (is_array($cached) && isset($cached['country'], $cached['region'])) {
        return $cached;
    }

    $geo = $empty;
    $response = wp_remote_get("http://ip-api.com/json/{$ip}?fields=status,countryCode,regionName", ['timeout' => 2]);
    if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
        $data = json_decode(wp_remote_retrieve_body($response), true);
        if ($data && ($data['status'] ?? '') === 'success') {
            $geo = [
                'country' => sanitize_text_field($data['countryCode'] ?? ''),
                'region'  => sanitize_text_field($data['regionName'] ?? ''),
            ];
        }
    }

    $ttl = ($geo['country'] !== '') ? 12 * HOUR_IN_SECONDS : 15 * MINUTE_IN_SECONDS;
    set_transient($cache_key, $geo, $ttl);

    return $geo;
}

// =============================================================================
// DADOS GEOGRÁFICOS PARA TARGETING (listas selecionáveis + audiência real)
// =============================================================================

/**
 * Emoji de bandeira a partir do código ISO-3166 alpha-2 (ex: 'MZ' → 🇲🇿).
 */
function imz_country_flag(string $code): string {
    $code = strtoupper(trim($code));
    if (!preg_match('/^[A-Z]{2}$/', $code)) return '';
    $flag = '';
    foreach (str_split($code) as $char) {
        $flag .= html_entity_decode('&#' . (127397 + ord($char)) . ';', ENT_QUOTES, 'UTF-8');
    }
    return $flag;
}

/**
 * Lista de países para o seletor de targeting, agrupada e em português.
 * @return array<string, array<string, string>> grupo => [código ISO => nome]
 */
function imz_get_target_countries_list(): array {
    return [
        'África' => [
            'MZ' => 'Moçambique',    'ZA' => 'África do Sul', 'AO' => 'Angola',
            'ZW' => 'Zimbabué',      'TZ' => 'Tanzânia',      'MW' => 'Maláui',
            'ZM' => 'Zâmbia',        'SZ' => 'Essuatíni',     'BW' => 'Botsuana',
            'NA' => 'Namíbia',       'LS' => 'Lesoto',        'KE' => 'Quénia',
            'NG' => 'Nigéria',       'GH' => 'Gana',          'CD' => 'RD Congo',
            'CV' => 'Cabo Verde',    'ST' => 'São Tomé e Príncipe', 'GW' => 'Guiné-Bissau',
            'SN' => 'Senegal',       'CI' => 'Costa do Marfim', 'CM' => 'Camarões',
            'UG' => 'Uganda',        'RW' => 'Ruanda',        'ET' => 'Etiópia',
            'EG' => 'Egito',         'MA' => 'Marrocos',      'DZ' => 'Argélia',
            'TN' => 'Tunísia',       'MG' => 'Madagáscar',    'MU' => 'Maurícia',
        ],
        'Europa' => [
            'PT' => 'Portugal',      'GB' => 'Reino Unido',   'FR' => 'França',
            'DE' => 'Alemanha',      'ES' => 'Espanha',       'IT' => 'Itália',
            'NL' => 'Países Baixos', 'CH' => 'Suíça',         'IE' => 'Irlanda',
            'BE' => 'Bélgica',       'SE' => 'Suécia',        'NO' => 'Noruega',
        ],
        'Américas e Resto do Mundo' => [
            'BR' => 'Brasil',        'US' => 'Estados Unidos', 'CA' => 'Canadá',
            'AE' => 'Emirados Árabes', 'QA' => 'Catar',        'SA' => 'Arábia Saudita',
            'CN' => 'China',         'IN' => 'Índia',          'AU' => 'Austrália',
            'TR' => 'Turquia',       'JP' => 'Japão',
        ],
    ];
}

/**
 * As 11 províncias de Moçambique para o seletor de targeting.
 * O valor guardado é o token que corresponde ao regionName do ip-api
 * (a comparação no filtro é parcial e insensível a acentos).
 *
 * @return array<string, string> rótulo PT => valor guardado
 */
function imz_get_mz_provinces_list(): array {
    return [
        'Cidade de Maputo'    => 'Maputo City',
        'Província de Maputo' => 'Maputo Province',
        'Gaza'                => 'Gaza',
        'Inhambane'           => 'Inhambane',
        'Sofala'              => 'Sofala',
        'Manica'              => 'Manica',
        'Tete'                => 'Tete',
        'Zambézia'            => 'Zambezia',
        'Nampula'             => 'Nampula',
        'Cabo Delgado'        => 'Cabo Delgado',
        'Niassa'              => 'Niassa',
    ];
}

/**
 * Geografias realmente observadas na audiência (tabela wp_imz_ad_stats),
 * com contagens. Cache de 1 hora. Alimenta os seletores com dados do banco.
 *
 * @return array{
 *     countries: array<string, int>,
 *     regions: array<string, int>,
 *     regions_by_country: array<string, array<string, int>>
 * }
 */
function imz_ads_get_observed_geo(): array {
    $cached = get_transient('imz_ads_observed_geo');
    if (is_array($cached) && isset($cached['countries'], $cached['regions'], $cached['regions_by_country'])) {
        return $cached;
    }

    $result = ['countries' => [], 'regions' => [], 'regions_by_country' => []];
    global $wpdb;
    $table = $wpdb->prefix . 'imz_ad_stats';
    if ($wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $table)) === $table) {
        foreach ($wpdb->get_results("SELECT country AS k, COUNT(*) AS total FROM $table WHERE country != '' GROUP BY country ORDER BY total DESC LIMIT 30") as $row) {
            $result['countries'][strtoupper($row->k)] = (int) $row->total;
        }
        foreach ($wpdb->get_results("SELECT region AS k, COUNT(*) AS total FROM $table WHERE region != '' GROUP BY region ORDER BY total DESC LIMIT 30") as $row) {
            $result['regions'][$row->k] = (int) $row->total;
        }
        // Regiões agrupadas por país (para o seletor mostrar regiões do país escolhido)
        foreach ($wpdb->get_results("SELECT country AS c, region AS k, COUNT(*) AS total FROM $table WHERE country != '' AND region != '' GROUP BY country, region ORDER BY total DESC LIMIT 80") as $row) {
            $cc = strtoupper($row->c);
            if (!isset($result['regions_by_country'][$cc])) $result['regions_by_country'][$cc] = [];
            if (count($result['regions_by_country'][$cc]) < 12) {
                $result['regions_by_country'][$cc][$row->k] = (int) $row->total;
            }
        }
    }

    set_transient('imz_ads_observed_geo', $result, HOUR_IN_SECONDS);
    return $result;
}
