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

// =============================================================================
// RELATÓRIOS DE ANÚNCIOS — helpers de agregação sobre wp_imz_ad_stats
// Usados pelo painel do anunciante ([imz_meus_anuncios]) e pelo admin.
// =============================================================================

/**
 * Garante que a tabela de stats existe. Devolve o nome da tabela ou null.
 */
function imz_ads_stats_table(): ?string {
    global $wpdb;
    $table = $wpdb->prefix . 'imz_ad_stats';
    if ($wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $table)) !== $table) {
        return null;
    }
    return $table;
}

/**
 * Totais de impressões e cliques de um anúncio (source_type = 'ad'),
 * opcionalmente limitados a um período. Cache de 5 minutos.
 *
 * @return array{impressions: int, clicks: int}
 */
function imz_ads_get_totals(int $ad_id, ?string $from = null, ?string $to = null): array {
    $empty = ['impressions' => 0, 'clicks' => 0];
    if (!$ad_id) return $empty;

    $cache_key = 'imz_ad_totals_' . $ad_id . '_' . md5((string) $from . '|' . (string) $to);
    $cached = get_transient($cache_key);
    if (is_array($cached)) return $cached;

    $table = imz_ads_stats_table();
    if (!$table) return $empty;

    global $wpdb;
    $sql = "SELECT
                SUM(event_type = 'impression') AS impressions,
                SUM(event_type = 'click') AS clicks
            FROM $table
            WHERE ad_id = %d AND source_type = 'ad'";
    $params = [$ad_id];
    if ($from) { $sql .= " AND event_date >= %s"; $params[] = $from . ' 00:00:00'; }
    if ($to)   { $sql .= " AND event_date <= %s"; $params[] = $to . ' 23:59:59'; }

    $row = $wpdb->get_row($wpdb->prepare($sql, $params));
    $totals = [
        'impressions' => (int) ($row->impressions ?? 0),
        'clicks'      => (int) ($row->clicks ?? 0),
    ];
    set_transient($cache_key, $totals, 5 * MINUTE_IN_SECONDS);
    return $totals;
}

/**
 * Totais por anúncio em lote (1 query) — substitui as queries por campanha do dashboard.
 *
 * @param  int[] $ad_ids
 * @return array<int, array{impressions: int, clicks: int}>
 */
function imz_ads_get_totals_bulk(array $ad_ids, ?string $from = null, ?string $to = null): array {
    $ad_ids = array_filter(array_map('absint', $ad_ids));
    if (empty($ad_ids)) return [];

    $table = imz_ads_stats_table();
    $result = array_fill_keys($ad_ids, ['impressions' => 0, 'clicks' => 0]);
    if (!$table) return $result;

    global $wpdb;
    $placeholders = implode(',', array_fill(0, count($ad_ids), '%d'));
    $sql = "SELECT ad_id,
                SUM(event_type = 'impression') AS impressions,
                SUM(event_type = 'click') AS clicks
            FROM $table
            WHERE ad_id IN ($placeholders) AND source_type = 'ad'";
    $params = $ad_ids;
    if ($from) { $sql .= " AND event_date >= %s"; $params[] = $from . ' 00:00:00'; }
    if ($to)   { $sql .= " AND event_date <= %s"; $params[] = $to . ' 23:59:59'; }
    $sql .= " GROUP BY ad_id";

    foreach ($wpdb->get_results($wpdb->prepare($sql, $params)) as $row) {
        $result[(int) $row->ad_id] = [
            'impressions' => (int) $row->impressions,
            'clicks'      => (int) $row->clicks,
        ];
    }
    return $result;
}

/**
 * Breakdown de dispositivos por anúncio em lote (1 query).
 *
 * @param  int[] $ad_ids
 * @return array<int, array{mobile: int, desktop: int, tablet: int}>
 */
function imz_ads_get_device_bulk(array $ad_ids): array {
    $ad_ids = array_filter(array_map('absint', $ad_ids));
    if (empty($ad_ids)) return [];

    $table = imz_ads_stats_table();
    $result = array_fill_keys($ad_ids, ['mobile' => 0, 'desktop' => 0, 'tablet' => 0]);
    if (!$table) return $result;

    global $wpdb;
    $placeholders = implode(',', array_fill(0, count($ad_ids), '%d'));
    $rows = $wpdb->get_results($wpdb->prepare(
        "SELECT ad_id, device_type, COUNT(*) AS total
         FROM $table WHERE ad_id IN ($placeholders)
         GROUP BY ad_id, device_type",
        $ad_ids
    ));
    foreach ($rows as $row) {
        $device = in_array($row->device_type, ['mobile', 'desktop', 'tablet'], true) ? $row->device_type : 'desktop';
        $result[(int) $row->ad_id][$device] += (int) $row->total;
    }
    return $result;
}

/**
 * Breakdown geográfico por anúncio em lote (1 query, top 5 por anúncio em PHP).
 *
 * @param  int[]  $ad_ids
 * @param  string $dim 'country' ou 'region'
 * @return array<int, array<object{k: string, total: int}>>
 */
function imz_ads_get_geo_breakdown_bulk(array $ad_ids, string $dim): array {
    if (!in_array($dim, ['country', 'region'], true)) return [];
    $ad_ids = array_filter(array_map('absint', $ad_ids));
    if (empty($ad_ids)) return [];

    $table = imz_ads_stats_table();
    $result = array_fill_keys($ad_ids, []);
    if (!$table) return $result;

    global $wpdb;
    $placeholders = implode(',', array_fill(0, count($ad_ids), '%d'));
    $rows = $wpdb->get_results($wpdb->prepare(
        "SELECT ad_id, $dim AS k, COUNT(*) AS total
         FROM $table WHERE ad_id IN ($placeholders) AND $dim != ''
         GROUP BY ad_id, $dim ORDER BY total DESC",
        $ad_ids
    ));
    foreach ($rows as $row) {
        $aid = (int) $row->ad_id;
        if (count($result[$aid]) < 5) {
            $result[$aid][] = (object) ['k' => $row->k, 'total' => (int) $row->total];
        }
    }
    return $result;
}

/**
 * Série diária de impressões e cliques (dias sem eventos preenchidos a zero).
 *
 * @param  int|null $ad_id null = todos os anúncios (source_type 'ad')
 * @return array{labels: string[], impressions: int[], clicks: int[]}
 */
function imz_ads_get_daily_series(?int $ad_id, string $from, string $to): array {
    $empty = ['labels' => [], 'impressions' => [], 'clicks' => []];
    $table = imz_ads_stats_table();

    $map = [];
    if ($table) {
        global $wpdb;
        $sql = "SELECT DATE(event_date) AS d,
                    SUM(event_type = 'impression') AS impressions,
                    SUM(event_type = 'click') AS clicks
                FROM $table
                WHERE source_type = 'ad' AND event_date >= %s AND event_date <= %s";
        $params = [$from . ' 00:00:00', $to . ' 23:59:59'];
        if ($ad_id) { $sql .= " AND ad_id = %d"; $params[] = $ad_id; }
        $sql .= " GROUP BY DATE(event_date) ORDER BY d ASC";

        foreach ($wpdb->get_results($wpdb->prepare($sql, $params)) as $row) {
            $map[$row->d] = ['impressions' => (int) $row->impressions, 'clicks' => (int) $row->clicks];
        }
    }

    $series = $empty;
    $cursor = strtotime($from);
    $end_ts = strtotime($to);
    while ($cursor !== false && $cursor <= $end_ts) {
        $date = date('Y-m-d', $cursor);
        $series['labels'][]      = date('d/m', $cursor);
        $series['impressions'][] = $map[$date]['impressions'] ?? 0;
        $series['clicks'][]      = $map[$date]['clicks'] ?? 0;
        $cursor = strtotime('+1 day', $cursor);
    }
    return $series;
}

/**
 * Breakdown por dimensão no período (todos os eventos), top 10.
 *
 * @param  string $dim Whitelist: device_type | country | region
 * @return array<object{k: string, total: int}>
 */
function imz_ads_get_breakdown(?int $ad_id, string $dim, string $from, string $to): array {
    if (!in_array($dim, ['device_type', 'country', 'region'], true)) return [];
    $table = imz_ads_stats_table();
    if (!$table) return [];

    global $wpdb;
    $sql = "SELECT $dim AS k, COUNT(*) AS total
            FROM $table
            WHERE source_type = 'ad' AND $dim != '' AND event_date >= %s AND event_date <= %s";
    $params = [$from . ' 00:00:00', $to . ' 23:59:59'];
    if ($ad_id) { $sql .= " AND ad_id = %d"; $params[] = $ad_id; }
    $sql .= " GROUP BY $dim ORDER BY total DESC LIMIT 10";

    return $wpdb->get_results($wpdb->prepare($sql, $params)) ?: [];
}

// =============================================================================
// VIEW "RELATÓRIOS" DO GESTOR ADMIN
// =============================================================================

/**
 * Renderiza a tab Relatórios (chamada por imz_render_ads_manager_page).
 */
function imz_render_ads_reports_view(string $base_url): void {
    $report_ad   = absint($_GET['report_ad'] ?? 0);
    $report_days = absint($_GET['report_days'] ?? 30);
    if (!in_array($report_days, [7, 30, 90], true)) $report_days = 30;

    $to   = current_time('Y-m-d');
    $from = date('Y-m-d', strtotime("-" . ($report_days - 1) . " days", current_time('timestamp')));

    $all_ads = get_posts([
        'post_type'      => 'imz_anuncio',
        'post_status'    => 'publish',
        'posts_per_page' => -1,
        'orderby'        => 'date',
        'order'          => 'DESC',
    ]);

    $series = imz_ads_get_daily_series($report_ad ?: null, $from, $to);
    $bulk   = imz_ads_get_totals_bulk(wp_list_pluck($all_ads, 'ID'), $from, $to);

    $devices   = imz_ads_get_breakdown($report_ad ?: null, 'device_type', $from, $to);
    $countries = imz_ads_get_breakdown($report_ad ?: null, 'country', $from, $to);
    $regions   = imz_ads_get_breakdown($report_ad ?: null, 'region', $from, $to);

    $csv_url = wp_nonce_url(add_query_arg([
        'action'      => 'imz_ads_export_csv',
        'report_ad'   => $report_ad,
        'report_days' => $report_days,
    ], admin_url('admin-post.php')), 'imz_ads_export_csv');
    ?>
    <div class="imz-report-card">
        <h3 style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:10px;">
            📈 Desempenho Diário
            <a href="<?php echo esc_url($csv_url); ?>" class="button button-secondary">⬇ Exportar CSV</a>
        </h3>
        <form method="get" style="display:flex; gap:10px; align-items:center; margin-bottom:16px; flex-wrap:wrap;">
            <?php // manter os parâmetros da página admin no GET ?>
            <input type="hidden" name="post_type" value="impulsionamento">
            <input type="hidden" name="page" value="imz_ads_manager">
            <input type="hidden" name="view" value="reports">
            <select name="report_ad">
                <option value="0">Todos os anúncios</option>
                <?php foreach ($all_ads as $ad) : ?>
                    <option value="<?php echo $ad->ID; ?>" <?php selected($report_ad, $ad->ID); ?>><?php echo esc_html($ad->post_title); ?></option>
                <?php endforeach; ?>
            </select>
            <select name="report_days">
                <option value="7" <?php selected($report_days, 7); ?>>Últimos 7 dias</option>
                <option value="30" <?php selected($report_days, 30); ?>>Últimos 30 dias</option>
                <option value="90" <?php selected($report_days, 90); ?>>Últimos 90 dias</option>
            </select>
            <button type="submit" class="button">Filtrar</button>
        </form>
        <div style="position:relative; height:300px;">
            <canvas id="imz-ads-chart"></canvas>
        </div>
    </div>

    <div class="imz-report-card">
        <h3>💰 Desempenho por Campanha (<?php echo esc_html($report_days); ?> dias)</h3>
        <table class="imz-ads-table">
            <thead>
                <tr><th>Anúncio</th><th>Estado</th><th>Impressões</th><th>Cliques</th><th>CTR</th><th>Investimento</th><th>CPM</th><th>CPC</th></tr>
            </thead>
            <tbody>
            <?php foreach ($all_ads as $ad) :
                $t = $bulk[$ad->ID] ?? ['impressions' => 0, 'clicks' => 0];
                $price = (float) get_post_meta($ad->ID, '_imz_ad_price', true);
                $status = get_post_meta($ad->ID, '_imz_ad_status', true) ?: 'pendente';
                $ctr = $t['impressions'] > 0 ? round(($t['clicks'] / $t['impressions']) * 100, 2) . '%' : '—';
                $cpm = $t['impressions'] > 0 && $price > 0 ? number_format($price / ($t['impressions'] / 1000), 2) . ' MT' : '—';
                $cpc = $t['clicks'] > 0 && $price > 0 ? number_format($price / $t['clicks'], 2) . ' MT' : '—';
            ?>
                <tr>
                    <td><strong><?php echo esc_html($ad->post_title); ?></strong></td>
                    <td><span class="imz-badge imz-badge-<?php echo esc_attr($status); ?>"><?php echo esc_html(ucfirst(str_replace('_', ' ', $status))); ?></span></td>
                    <td><?php echo number_format($t['impressions']); ?></td>
                    <td><?php echo number_format($t['clicks']); ?></td>
                    <td><?php echo esc_html($ctr); ?></td>
                    <td><?php echo $price > 0 ? number_format($price) . ' MT' : '—'; ?></td>
                    <td><?php echo esc_html($cpm); ?></td>
                    <td><?php echo esc_html($cpc); ?></td>
                </tr>
            <?php endforeach; ?>
            <?php if (empty($all_ads)) : ?>
                <tr><td colspan="8" style="color:#9ca3af;">Nenhum anúncio encontrado.</td></tr>
            <?php endif; ?>
            </tbody>
        </table>
    </div>

    <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(240px, 1fr)); gap:20px;">
        <?php
        $breakdown_blocks = [
            '📱 Dispositivos' => $devices,
            '🌍 Países'      => $countries,
            '📍 Províncias'  => $regions,
        ];
        foreach ($breakdown_blocks as $block_title => $rows) : ?>
        <div class="imz-report-card" style="margin-bottom:0;">
            <h3><?php echo esc_html($block_title); ?></h3>
            <?php if (empty($rows)) : ?>
                <p style="color:#9ca3af; font-size:13px;">Sem dados no período.</p>
            <?php else : ?>
                <table class="imz-ads-table">
                    <tbody>
                    <?php foreach ($rows as $r) : ?>
                        <tr><td><?php echo esc_html($r->k); ?></td><td style="text-align:right; font-weight:700;"><?php echo number_format((int) $r->total); ?></td></tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>
            <?php endif; ?>
        </div>
        <?php endforeach; ?>
    </div>

    <script>
    document.addEventListener('DOMContentLoaded', function () {
        var canvas = document.getElementById('imz-ads-chart');
        if (!canvas || typeof Chart === 'undefined') return;
        var data = <?php echo wp_json_encode($series); ?>;
        new Chart(canvas.getContext('2d'), {
            type: 'line',
            data: {
                labels: data.labels,
                datasets: [
                    { label: 'Impressões', data: data.impressions, borderColor: 'rgba(59,130,246,1)', backgroundColor: 'rgba(59,130,246,0.10)', fill: true, tension: 0.4, pointRadius: 3, borderWidth: 2 },
                    { label: 'Cliques', data: data.clicks, borderColor: 'rgba(16,185,129,1)', backgroundColor: 'rgba(16,185,129,0.10)', fill: true, tension: 0.4, pointRadius: 3, borderWidth: 2 }
                ]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                interaction: { mode: 'index', intersect: false },
                scales: { y: { beginAtZero: true, ticks: { precision: 0 } } }
            }
        });
    });
    </script>
    <?php
}

// =============================================================================
// EXPORTAÇÃO CSV (admin-post.php)
// =============================================================================

add_action('admin_post_imz_ads_export_csv', 'imz_ads_handle_csv_export');
function imz_ads_handle_csv_export(): void {
    if (!current_user_can('manage_options') || !wp_verify_nonce($_GET['_wpnonce'] ?? '', 'imz_ads_export_csv')) {
        wp_die('Sem permissão para exportar este relatório.');
    }

    $report_ad   = absint($_GET['report_ad'] ?? 0);
    $report_days = absint($_GET['report_days'] ?? 30);
    if (!in_array($report_days, [7, 30, 90], true)) $report_days = 30;

    $to   = current_time('Y-m-d');
    $from = date('Y-m-d', strtotime("-" . ($report_days - 1) . " days", current_time('timestamp')));

    $series = imz_ads_get_daily_series($report_ad ?: null, $from, $to);
    $ad_label = $report_ad ? get_the_title($report_ad) : 'Todos os anúncios';

    nocache_headers();
    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename=relatorio-anuncios-' . $from . '-a-' . $to . '.csv');

    $out = fopen('php://output', 'w');
    echo "\xEF\xBB\xBF"; // BOM UTF-8 para o Excel ler acentos corretamente

    fputcsv($out, ['Relatório de Anúncios', $ad_label, $from . ' a ' . $to]);
    fputcsv($out, ['Data', 'Impressões', 'Cliques', 'CTR (%)']);

    $total_imp = 0;
    $total_clk = 0;
    $day_count = count($series['labels']);
    $year_cursor = strtotime($from);
    for ($i = 0; $i < $day_count; $i++) {
        $imp = $series['impressions'][$i];
        $clk = $series['clicks'][$i];
        $total_imp += $imp;
        $total_clk += $clk;
        $ctr = $imp > 0 ? round(($clk / $imp) * 100, 2) : 0;
        fputcsv($out, [date('Y-m-d', $year_cursor), $imp, $clk, $ctr]);
        $year_cursor = strtotime('+1 day', $year_cursor);
    }
    $total_ctr = $total_imp > 0 ? round(($total_clk / $total_imp) * 100, 2) : 0;
    fputcsv($out, ['TOTAL', $total_imp, $total_clk, $total_ctr]);

    fclose($out);
    exit;
}
