<?php

/**
 * Facebook Ads – Analytics & AI Advisor Controller v1.1
 *
 * - جلب إحصاءات تفصيلية من Meta Insights API
 * - تحليل الأداء بالذكاء الاصطناعي
 * - توصيات للحملات المستقبلية
 */
class FbAdsAnalyticsController
{
    private const FB_API = 'https://graph.facebook.com/v19.0';

    private function cfg(): array
    {
        return db()->query("SELECT * FROM fb_settings LIMIT 1")->fetch(\PDO::FETCH_ASSOC) ?: [];
    }

    private function getCampaign(int $id): ?array
    {
        $stmt = db()->prepare("
            SELECT c.*, p.title AS product_title, p.featured_image,
                   p.price, p.currency
            FROM fb_campaigns c
            LEFT JOIN products p ON p.id = c.product_id
            WHERE c.id = ?
        ");
        $stmt->execute([$id]);
        return $stmt->fetch(\PDO::FETCH_ASSOC) ?: null;
    }

    private function json(array $data, int $code = 200): never
    {
        http_response_code($code);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($data, JSON_UNESCAPED_UNICODE);
        exit;
    }

    // ── Analytics Dashboard ───────────────────────────────────────────
    public function index(int $id): void
    {
        FbAdsLicenseGuard::check();
        FbLang::load();

        $campaign = $this->getCampaign($id);
        if (!$campaign) { http_response_code(404); return; }
        $cfg = $this->cfg();

        // Daily insights for charts
        $insights = db()->prepare("
            SELECT * FROM fb_insights WHERE campaign_id = ?
            ORDER BY date ASC LIMIT 90
        ");
        $insights->execute([$id]);
        $insights = $insights->fetchAll(\PDO::FETCH_ASSOC);

        // Decode breakdown JSON
        foreach ($insights as &$row) {
            $row['age_breakdown']    = json_decode($row['age_breakdown']    ?? '[]', true) ?: [];
            $row['gender_breakdown'] = json_decode($row['gender_breakdown'] ?? '[]', true) ?: [];
            $row['region_breakdown'] = json_decode($row['region_breakdown'] ?? '[]', true) ?: [];
        }
        unset($row);

        // Aggregate age & gender across all days
        $ageData    = $this->aggregateBreakdown($insights, 'age_breakdown', 'age_range');
        $genderData = $this->aggregateBreakdown($insights, 'gender_breakdown', 'gender');
        $regionData = $this->aggregateBreakdown($insights, 'region_breakdown', 'region');

        // Latest AI advice
        $lastAdvice = db()->prepare("
            SELECT * FROM fb_ai_insights WHERE campaign_id = ?
            ORDER BY created_at DESC LIMIT 1
        ");
        $lastAdvice->execute([$id]);
        $lastAdvice = $lastAdvice->fetch(\PDO::FETCH_ASSOC);
        if ($lastAdvice) {
            $lastAdvice['next_config'] = json_decode($lastAdvice['next_config'] ?? '{}', true) ?: [];
        }

        $aiAvailable = $this->isAiAvailable();
        $isConfigured = !empty($cfg['access_token']) && !empty($cfg['ad_account_id']);

        require ROOT_PATH . '/plugins/FacebookAds/templates/analytics.php';
    }

    // ── Fetch full insights from Meta API ─────────────────────────────
    public function fetchInsights(int $id): void
    {
        $cfg = $this->cfg();
        if (empty($cfg['access_token'])) {
            $this->json(['success' => false, 'message' => 'Not configured.']);
        }

        $campaign = $this->getCampaign($id);
        if (!$campaign || empty($campaign['fb_campaign_id'])) {
            $this->json(['success' => false, 'message' => 'Campaign not found or not launched.']);
        }

        $token      = $cfg['access_token'];
        $fbCampaign = $campaign['fb_campaign_id'];
        $pdo        = db();

        // ── Fetch overall campaign stats ──────────────────────────────
        $overall = $this->fbGet("/{$fbCampaign}/insights", [
            'fields'       => 'impressions,reach,clicks,unique_clicks,spend,ctr,cpc,cpm,frequency,actions,action_values',
            'date_preset'  => 'lifetime',
            'access_token' => $token,
        ]);

        // ── Fetch daily breakdown ─────────────────────────────────────
        $daily = $this->fbGet("/{$fbCampaign}/insights", [
            'fields'       => 'impressions,reach,clicks,spend,ctr,cpc,cpm,frequency,actions',
            'time_increment' => 1,
            'date_preset'  => 'lifetime',
            'access_token' => $token,
        ]);

        // ── Fetch age/gender breakdown ────────────────────────────────
        $ageGender = $this->fbGet("/{$fbCampaign}/insights", [
            'fields'       => 'impressions,clicks,spend,reach',
            'breakdowns'   => 'age,gender',
            'date_preset'  => 'lifetime',
            'access_token' => $token,
        ]);

        // ── Fetch region breakdown ────────────────────────────────────
        $region = $this->fbGet("/{$fbCampaign}/insights", [
            'fields'       => 'impressions,clicks,spend,reach',
            'breakdowns'   => 'region',
            'date_preset'  => 'lifetime',
            'access_token' => $token,
        ]);

        // ── Process overall stats ─────────────────────────────────────
        $overallData = $overall['data'][0] ?? [];
        if ($overallData) {
            $purchases     = 0;
            $purchaseValue = 0.0;
            $leads         = 0;

            foreach ($overallData['actions'] ?? [] as $action) {
                if (in_array($action['action_type'], ['purchase', 'offsite_conversion.fb_pixel_purchase'])) {
                    $purchases += (int)$action['value'];
                }
                if ($action['action_type'] === 'lead') {
                    $leads += (int)$action['value'];
                }
            }
            foreach ($overallData['action_values'] ?? [] as $av) {
                if (in_array($av['action_type'], ['purchase', 'offsite_conversion.fb_pixel_purchase'])) {
                    $purchaseValue += (float)$av['value'];
                }
            }

            $pdo->prepare("
                UPDATE fb_campaigns SET
                    impressions=:imp, reach=:reach, clicks=:clicks,
                    unique_clicks=:uc, spend=:spend, ctr=:ctr,
                    cpc=:cpc, cpm=:cpm, frequency=:freq,
                    purchases=:purch, purchase_value=:pval, leads=:leads,
                    last_sync=NOW()
                WHERE id=:id
            ")->execute([
                ':imp'   => (int)($overallData['impressions']    ?? 0),
                ':reach' => (int)($overallData['reach']           ?? 0),
                ':clicks'=> (int)($overallData['clicks']          ?? 0),
                ':uc'    => (int)($overallData['unique_clicks']   ?? 0),
                ':spend' => (float)($overallData['spend']         ?? 0),
                ':ctr'   => (float)($overallData['ctr']           ?? 0),
                ':cpc'   => (float)($overallData['cpc']           ?? 0),
                ':cpm'   => (float)($overallData['cpm']           ?? 0),
                ':freq'  => (float)($overallData['frequency']     ?? 0),
                ':purch' => $purchases,
                ':pval'  => $purchaseValue,
                ':leads' => $leads,
                ':id'    => $id,
            ]);
        }

        // ── Process daily data ────────────────────────────────────────
        $dailyCount = 0;
        foreach ($daily['data'] ?? [] as $day) {
            $dayPurchases = 0;
            foreach ($day['actions'] ?? [] as $a) {
                if (str_contains($a['action_type'], 'purchase')) $dayPurchases += (int)$a['value'];
            }

            $pdo->prepare("
                INSERT INTO fb_insights
                    (campaign_id, date, impressions, reach, clicks, spend, ctr, cpc, cpm, frequency, purchases)
                VALUES
                    (:cid, :date, :imp, :reach, :clicks, :spend, :ctr, :cpc, :cpm, :freq, :purch)
                ON DUPLICATE KEY UPDATE
                    impressions=VALUES(impressions), reach=VALUES(reach),
                    clicks=VALUES(clicks), spend=VALUES(spend),
                    ctr=VALUES(ctr), cpc=VALUES(cpc), cpm=VALUES(cpm),
                    frequency=VALUES(frequency), purchases=VALUES(purchases)
            ")->execute([
                ':cid'    => $id,
                ':date'   => $day['date_start'] ?? date('Y-m-d'),
                ':imp'    => (int)($day['impressions'] ?? 0),
                ':reach'  => (int)($day['reach']       ?? 0),
                ':clicks' => (int)($day['clicks']      ?? 0),
                ':spend'  => (float)($day['spend']     ?? 0),
                ':ctr'    => (float)($day['ctr']        ?? 0),
                ':cpc'    => (float)($day['cpc']        ?? 0),
                ':cpm'    => (float)($day['cpm']        ?? 0),
                ':freq'   => (float)($day['frequency']  ?? 0),
                ':purch'  => $dayPurchases,
            ]);
            $dailyCount++;
        }

        // ── Process age/gender breakdown ──────────────────────────────
        // Store aggregated breakdown on the most recent insight row
        if (!empty($ageGender['data'])) {
            $ageBreakdown    = [];
            $genderBreakdown = [];

            foreach ($ageGender['data'] as $row) {
                $age    = $row['age']    ?? 'unknown';
                $gender = $row['gender'] ?? 'unknown';
                $key    = $age . '_' . $gender;

                if (!isset($ageBreakdown[$age])) {
                    $ageBreakdown[$age] = ['impressions' => 0, 'clicks' => 0, 'spend' => 0];
                }
                $ageBreakdown[$age]['impressions'] += (int)($row['impressions'] ?? 0);
                $ageBreakdown[$age]['clicks']      += (int)($row['clicks']      ?? 0);
                $ageBreakdown[$age]['spend']       += (float)($row['spend']     ?? 0);

                if (!isset($genderBreakdown[$gender])) {
                    $genderBreakdown[$gender] = ['impressions' => 0, 'clicks' => 0, 'spend' => 0];
                }
                $genderBreakdown[$gender]['impressions'] += (int)($row['impressions'] ?? 0);
                $genderBreakdown[$gender]['clicks']      += (int)($row['clicks']      ?? 0);
                $genderBreakdown[$gender]['spend']       += (float)($row['spend']     ?? 0);
            }

            // Update the latest insight row with breakdown
            $pdo->prepare("
                UPDATE fb_insights SET age_breakdown=?, gender_breakdown=?
                WHERE campaign_id=? ORDER BY date DESC LIMIT 1
            ")->execute([
                json_encode(array_map(fn($k,$v) => array_merge(['age_range'=>$k],$v), array_keys($ageBreakdown), $ageBreakdown)),
                json_encode(array_map(fn($k,$v) => array_merge(['gender'=>$k],$v), array_keys($genderBreakdown), $genderBreakdown)),
                $id,
            ]);
        }

        // ── Process region breakdown ──────────────────────────────────
        if (!empty($region['data'])) {
            $regionData = [];
            foreach ($region['data'] as $row) {
                $r = $row['region'] ?? 'unknown';
                if (!isset($regionData[$r])) {
                    $regionData[$r] = ['impressions' => 0, 'clicks' => 0, 'spend' => 0, 'reach' => 0];
                }
                $regionData[$r]['impressions'] += (int)($row['impressions'] ?? 0);
                $regionData[$r]['clicks']      += (int)($row['clicks']      ?? 0);
                $regionData[$r]['spend']       += (float)($row['spend']     ?? 0);
                $regionData[$r]['reach']       += (int)($row['reach']       ?? 0);
            }
            arsort($regionData); // sort by impressions desc
            $regionArr = array_map(fn($k,$v) => array_merge(['region'=>$k],$v), array_keys($regionData), $regionData);
            $pdo->prepare("UPDATE fb_insights SET region_breakdown=? WHERE campaign_id=? ORDER BY date DESC LIMIT 1")
                ->execute([json_encode(array_slice($regionArr, 0, 10)), $id]);
        }

        $this->json([
            'success'       => true,
            'message'       => "Synced successfully!",
            'daily_records' => $dailyCount,
            'overall'       => $overallData,
        ]);
    }

    // ── AI Advisor Page ───────────────────────────────────────────────
    public function aiAdvisorPage(int $id): void
    {
        FbAdsLicenseGuard::check();
        FbLang::load();

        $campaign = $this->getCampaign($id);
        if (!$campaign) { http_response_code(404); return; }

        $insights = db()->prepare("SELECT * FROM fb_insights WHERE campaign_id=? ORDER BY date ASC");
        $insights->execute([$id]);
        $insights = $insights->fetchAll(\PDO::FETCH_ASSOC);

        $allAdvice = db()->prepare("SELECT * FROM fb_ai_insights WHERE campaign_id=? ORDER BY created_at DESC LIMIT 5");
        $allAdvice->execute([$id]);
        $allAdvice = $allAdvice->fetchAll(\PDO::FETCH_ASSOC);
        foreach ($allAdvice as &$a) {
            $a['next_config'] = json_decode($a['next_config'] ?? '{}', true) ?: [];
        }
        unset($a);

        $aiAvailable = $this->isAiAvailable();
        $cfg = $this->cfg();

        require ROOT_PATH . '/plugins/FacebookAds/templates/ai_advisor.php';
    }

    // ── AI Analysis ───────────────────────────────────────────────────
    public function aiAdvisor(int $id): void
    {
        $this->json(['success' => false, 'message' => 'Use GET request.']);
        // Handled below via POST
    }

    public function runAiAnalysis(int $id): void
    {
        header('Content-Type: application/json; charset=utf-8');

        if (!$this->isAiAvailable()) {
            echo json_encode(['success' => false, 'message' => 'AI not configured.']); exit;
        }

        $campaign = $this->getCampaign($id);
        if (!$campaign) { echo json_encode(['success' => false, 'message' => 'Not found.']); exit; }

        $pdo = db();

        // Get all insights
        $insights = $pdo->prepare("SELECT * FROM fb_insights WHERE campaign_id=? ORDER BY date ASC");
        $insights->execute([$id]);
        $insights = $insights->fetchAll(\PDO::FETCH_ASSOC);

        if (empty($insights)) {
            echo json_encode(['success' => false, 'message' => 'No insights data. Fetch stats first.']); exit;
        }

        // Build summary for AI
        $totalDays     = count($insights);
        $totalSpend    = array_sum(array_column($insights, 'spend'));
        $totalClicks   = array_sum(array_column($insights, 'clicks'));
        $totalImpress  = array_sum(array_column($insights, 'impressions'));
        $totalPurch    = array_sum(array_column($insights, 'purchases'));
        $avgCtr        = $totalImpress > 0 ? round(($totalClicks/$totalImpress)*100, 3) : 0;
        $avgCpc        = $totalClicks > 0 ? round($totalSpend/$totalClicks, 2) : 0;
        $avgCpm        = $totalImpress > 0 ? round(($totalSpend/$totalImpress)*1000, 2) : 0;
        $roas          = $totalSpend > 0 && $campaign['purchase_value'] > 0
                        ? round($campaign['purchase_value'] / $totalSpend, 2) : 0;

        // Best & worst days
        usort($insights, fn($a,$b) => $b['clicks'] <=> $a['clicks']);
        $bestDay  = $insights[0] ?? null;
        $worstDay = end($insights) ?: null;

        // Age breakdown from last record
        $lastInsight    = $pdo->prepare("SELECT age_breakdown, gender_breakdown, region_breakdown FROM fb_insights WHERE campaign_id=? ORDER BY date DESC LIMIT 1");
        $lastInsight->execute([$id]);
        $lastInsight    = $lastInsight->fetch(\PDO::FETCH_ASSOC) ?: [];
        $ageBreakdown   = json_decode($lastInsight['age_breakdown']    ?? '[]', true) ?: [];
        $genderBreakdown= json_decode($lastInsight['gender_breakdown'] ?? '[]', true) ?: [];

        // Find best age group
        $bestAge = 'Unknown';
        if (!empty($ageBreakdown)) {
            usort($ageBreakdown, fn($a,$b) => ($b['clicks']??0) <=> ($a['clicks']??0));
            $bestAge = $ageBreakdown[0]['age_range'] ?? 'Unknown';
        }

        $targeting = json_decode($campaign['targeting'] ?? '{}', true);
        $countries  = implode(', ', $targeting['geo_locations']['countries'] ?? []);
        $currentAge = ($targeting['age_min']??'?').'-'.($targeting['age_max']??'?');
        $currency   = $campaign['currency'] ?? 'DZD';

        $dialectInstr = \Core\App\Services\AiService::getDialectInstruction(null, 'ar');

        $prompt = <<<PROMPT
{$dialectInstr}

أنت مستشار تسويق رقمي خبير. حلّل إحصاءات هذه الحملة الإعلانية على Facebook وقدّم توصيات احترافية.

=== بيانات الحملة ===
المنتج: {$campaign['product_title']}
الهدف: {$campaign['objective']}
الميزانية اليومية: {$campaign['daily_budget']} {$currency} (بالسنت)
المدة: {$campaign['duration_days']} يوم
الاستهداف الحالي: {$countries} | عمر {$currentAge}

=== الإحصاءات الفعلية ===
إجمالي الأيام: {$totalDays}
مشاهدات: {$totalImpress}
نقرات: {$totalClicks}
إنفاق: {$totalSpend} {$currency}
مشتريات: {$totalPurch}
ROAS: {$roas}x (عائد الإنفاق الإعلاني)
متوسط CTR: {$avgCtr}%
متوسط CPC: {$avgCpc} {$currency}
متوسط CPM: {$avgCpm} {$currency}
أفضل يوم (نقرات): {$bestDay['date']} ({$bestDay['clicks']} نقرة، {$bestDay['spend']} إنفاق)
الفئة العمرية الأكثر تفاعلاً: {$bestAge}

=== معايير الأداء للمقارنة ===
CTR جيد: > 1%، ممتاز: > 2%
CPC جيد: < 5 {$currency}
ROAS جيد: > 2x، ممتاز: > 4x

أعطِ تحليلاً شاملاً بصيغة JSON فقط:
{
  "score": 75,
  "performance": "good|average|poor",
  "summary": "ملخص عام بجملتين",
  "strengths": ["نقطة قوة 1", "نقطة قوة 2"],
  "weaknesses": ["نقطة ضعف 1", "نقطة ضعف 2"],
  "insights": [
    {"title": "عنوان الملاحظة", "detail": "شرح تفصيلي", "type": "positive|negative|neutral"}
  ],
  "recommendations": [
    {"priority": "high|medium|low", "action": "الإجراء المحدد", "reason": "السبب", "expected_impact": "التأثير المتوقع"}
  ],
  "next_campaign": {
    "budget_suggestion": 600,
    "duration_suggestion": 10,
    "age_min": 25,
    "age_max": 40,
    "ad_copy_tips": ["نصيحة للنص الإعلاني"],
    "best_day_to_run": "الإثنين والأربعاء",
    "audience_refinement": "تضييق الجمهور على النساء 25-35 المهتمات بـ..."
  }
}
PROMPT;

        try {
            $ai      = \Core\App\Services\AiService::fromActiveProvider();
            $content = $ai->generate($prompt, [
                'system'     => 'You are a Facebook Ads performance analyst. Return JSON only, no markdown.',
                'max_tokens' => 1500,
            ]);

            $content = trim(preg_replace('/^```(?:json)?\s*/m', '', $content));
            $content = trim(preg_replace('/```\s*$/m', '', $content));
            $result  = json_decode($content, true);

            if (!is_array($result)) {
                if (preg_match('/\{.*\}/s', $content, $m)) {
                    $result = json_decode($m[0], true);
                }
            }

            if (!is_array($result) || empty($result['summary'])) {
                echo json_encode(['success' => false, 'message' => 'AI returned invalid format.', 'raw' => substr($content, 0, 300)]); exit;
            }

            // Save to DB
            $nextConfig = json_encode($result['next_campaign'] ?? []);
            $pdo->prepare("
                INSERT INTO fb_ai_insights (campaign_id, analysis, score, next_config)
                VALUES (?, ?, ?, ?)
            ")->execute([$id, json_encode($result, JSON_UNESCAPED_UNICODE), $result['score'] ?? 0, $nextConfig]);

            echo json_encode(['success' => true, 'analysis' => $result]);

        } catch (\Throwable $e) {
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
        exit;
    }

    // ── Helpers ───────────────────────────────────────────────────────
    private function aggregateBreakdown(array $insights, string $field, string $keyField): array
    {
        $agg = [];
        foreach ($insights as $row) {
            foreach ($row[$field] ?? [] as $item) {
                $key = $item[$keyField] ?? 'unknown';
                if (!isset($agg[$key])) $agg[$key] = ['impressions'=>0,'clicks'=>0,'spend'=>0.0];
                $agg[$key]['impressions'] += (int)($item['impressions']   ?? 0);
                $agg[$key]['clicks']      += (int)($item['clicks']        ?? 0);
                $agg[$key]['spend']       += (float)($item['spend']       ?? 0);
            }
        }
        arsort($agg);
        return array_map(fn($k,$v)=>array_merge([$keyField=>$k],$v), array_keys($agg), $agg);
    }

    private function isAiAvailable(): bool
    {
        try {
            return (bool) db()->query("SELECT COUNT(*) FROM ai_settings WHERE api_key!='' AND is_active=1")->fetchColumn();
        } catch (\Throwable $e) { return false; }
    }

    private function fbGet(string $endpoint, array $params): array
    {
        $url = self::FB_API . $endpoint . '?' . http_build_query($params);
        $ch  = curl_init($url);
        curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>30,CURLOPT_SSL_VERIFYPEER=>false]);
        $res = curl_exec($ch); curl_close($ch);
        return json_decode($res ?: '{}', true) ?: [];
    }
}
