<?php

namespace Core\App\Controllers;

use Core\App\Services\AiService;
use Core\App\Models\GeminiSettingModel;
use Core\App\Services\AutoSeoService;
use Core\App\Services\GeminiImageService;
use Core\App\Services\UploadService;
use Core\System\Language;

class AiController
{
    /* =====================================================
       SETTINGS PAGE
    ===================================================== */
    public function settings()
    {
        $autoSeoService = new AutoSeoService();
        $providers      = $this->loadAllProviders();
        $activeProvider = $this->getActiveProvider();
        $autoSeoEnabled = $autoSeoService->isEnabled();
        require ROOT_PATH . '/admin/templates/header.php';
        require ROOT_PATH . '/admin/templates/settings/ai_settings.php';
        require ROOT_PATH . '/admin/templates/footer.php';
    }

    /* =====================================================
       SAVE SETTINGS
    ===================================================== */
    public function save()
    {
        $db             = \db();
        $autoSeoService = new AutoSeoService($db);
        $activeProvider = trim($_POST['active_provider'] ?? 'gemini');
        $providerList   = ['gemini', 'claude', 'openai'];
        $autoSeoEnabled = !empty($_POST['auto_seo_enabled']) ? 1 : 0;

        foreach ($providerList as $prov) {
            $apiKey  = trim($_POST["{$prov}_api_key"] ?? '');
            $model   = trim($_POST["{$prov}_model"]   ?? '');
            $dialect = trim($_POST['dialect']         ?? 'fusha');
            if (empty($apiKey)) continue;
            $isActive = ($prov === $activeProvider) ? 1 : 0;
            $imageGenerationEnabled = ($prov === 'gemini' && !empty($_POST['gemini_image_generation_enabled'])) ? 1 : 0;
            $imageModel = $prov === 'gemini' ? trim((string)($_POST['gemini_image_model'] ?? '')) : null;
            $exists   = $db->prepare("SELECT id FROM ai_settings WHERE provider = ? LIMIT 1");
            $exists->execute([$prov]);
            if ($exists->fetchColumn()) {
                if ($prov === 'gemini') {
                    $db->prepare("UPDATE ai_settings SET api_key=:k, is_active=:a, model=:m, dialect=:d, auto_seo_enabled=:auto, image_generation_enabled=:ige, image_model=:im WHERE provider=:p")
                       ->execute([':k'=>$apiKey,':a'=>$isActive,':m'=>$model,':d'=>$dialect,':auto'=>$autoSeoEnabled,':ige'=>$imageGenerationEnabled, ':im'=>$imageModel, ':p'=>$prov]);
                } else {
                    $db->prepare("UPDATE ai_settings SET api_key=:k, is_active=:a, model=:m, dialect=:d, auto_seo_enabled=:auto WHERE provider=:p")
                       ->execute([':k'=>$apiKey,':a'=>$isActive,':m'=>$model,':d'=>$dialect,':auto'=>$autoSeoEnabled,':p'=>$prov]);
                }
            } else {
                if ($prov === 'gemini') {
                    $db->prepare("INSERT INTO ai_settings (provider,api_key,is_active,model,dialect,auto_seo_enabled,image_generation_enabled,image_model) VALUES (?,?,?,?,?,?,?,?)")
                       ->execute([$prov,$apiKey,$isActive,$model,$dialect,$autoSeoEnabled,$imageGenerationEnabled,$imageModel]);
                } else {
                    $db->prepare("INSERT INTO ai_settings (provider,api_key,is_active,model,dialect,auto_seo_enabled) VALUES (?,?,?,?,?,?)")
                       ->execute([$prov,$apiKey,$isActive,$model,$dialect,$autoSeoEnabled]);
                }
            }
        }
        $db->prepare("UPDATE ai_settings SET is_active=0, auto_seo_enabled=? WHERE provider!=?")->execute([$autoSeoEnabled, $activeProvider]);
        $_SESSION['flash_success'] = __('ai.saved','AI settings saved successfully');
        header('Location: /admin/settings/ai');
        exit;
    }

    /* =====================================================
       LIST MODELS (AJAX)
    ===================================================== */
    public function listModels()
    {
        header('Content-Type: application/json');
        $provider = trim($_POST['provider'] ?? '');
        $apiKey   = trim($_POST['api_key']  ?? '');
        if (!$provider || !$apiKey) {
            echo json_encode(['success'=>false,'error'=>'Provider and API key required']); exit;
        }
        try {
            $service = new AiService(['provider'=>$provider,'api_key'=>$apiKey,'model'=>'']);
            echo json_encode(['success'=>true,'models'=>$service->listModels()]);
        } catch (\Throwable $e) {
            echo json_encode(['success'=>false,'error'=>$e->getMessage()]);
        }
        exit;
    }

    /* =====================================================
       TEST CONNECTION (AJAX)
    ===================================================== */
    public function testConnection()
    {
        header('Content-Type: application/json');
        $provider = trim($_POST['provider'] ?? '');
        $apiKey   = trim($_POST['api_key']  ?? '');
        $model    = trim($_POST['model']    ?? '');
        try {
            $service = new AiService(['provider'=>$provider,'api_key'=>$apiKey,'model'=>$model]);
            echo json_encode($service->testConnection());
        } catch (\Throwable $e) {
            echo json_encode(['success'=>false,'error'=>$e->getMessage()]);
        }
        exit;
    }

    /* =====================================================
       GENERATE PRODUCT DESCRIPTION (AJAX)
    ===================================================== */
    public function generateProductDescription()
    {
        header('Content-Type: application/json; charset=utf-8');

        try {
            $token = trim((string)($_POST['_csrf'] ?? ''));
            if ($token === '' || empty($_SESSION['_csrf']) || !hash_equals((string) $_SESSION['_csrf'], $token)) {
                $this->jsonResponse([
                    'success' => false,
                    'message' => __('ai.error.csrf', 'Security error'),
                ], 419);
            }

            $title = trim((string)($_POST['title'] ?? ''));
            if ($title === '') {
                $this->jsonResponse([
                    'success' => false,
                    'message' => __('ai.error.missing_title', 'Title is required'),
                ], 422);
            }

            $service = AiService::fromActiveProvider();
            $lang    = Language::code();
            $dialectLine = $service->buildDialectInstruction($lang);

            $prompt = "{$dialectLine}\n\n"
                . "You are a content writer for an online store.\n\n"
                . "Rules:\n"
                . "- Do not write titles or introductions.\n"
                . "- Do not use formatting or markdown.\n"
                . "- Write in a natural human e-commerce style.\n"
                . "- Optimize for SEO naturally.\n\n"
                . "Task:\n"
                . "1) Write ONE short sentence as short description.\n"
                . "2) Write ONE short paragraph (2-4 sentences) as full description.\n\n"
                . "Product: {$title}\n\n"
                . "Return strictly:\nSHORT: ...\nFULL: ...";

            $text = $service->generate($prompt, ['max_tokens' => 512]);
            preg_match('/SHORT:\s*(.+)/u', $text, $sm);
            preg_match('/FULL:\s*(.+)/us', $text, $fm);

            $this->jsonResponse([
                'success' => true,
                'short' => trim($sm[1] ?? ''),
                'full' => trim($fm[1] ?? ''),
            ]);
        } catch (\Throwable $e) {
            $this->jsonResponse([
                'success' => false,
                'message' => $e->getMessage(),
            ], 500);
        }
    }




    private function jsonResponse(array $payload, int $statusCode = 200): void
    {
        http_response_code($statusCode);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }


    /* =====================================================
       GENERATE PRODUCT SEO (AJAX)
    ===================================================== */
    public function generateProductSeo()
    {
        header('Content-Type: application/json; charset=utf-8');

        try {
            $token = $_POST['_csrf'] ?? '';
            if (empty($token) || empty($_SESSION['_csrf']) || !hash_equals($_SESSION['_csrf'], $token)) {
                throw new \Exception(__('ai.error.csrf', 'Security error'));
            }

            $title = trim((string)($_POST['title'] ?? ''));
            if ($title === '') {
                throw new \Exception(__('ai.error.missing_title', 'Title is required'));
            }

            $shortDescription = trim((string)($_POST['short_description'] ?? ''));
            $description      = trim((string)($_POST['description'] ?? ''));
            $price            = trim((string)($_POST['price'] ?? ''));
            $currency         = trim((string)($_POST['currency'] ?? ''));
            $category         = trim((string)($_POST['category'] ?? ''));
            $featuredImage    = trim((string)($_POST['featured_image'] ?? ''));
            $lang             = Language::code() ?: 'ar';

            $service = AiService::fromActiveProvider();
            $dialectLine = $service->buildDialectInstruction($lang);

            $system = $lang === 'ar'
                ? $dialectLine . "\n\n" . 'أنت خبير SEO و Open Graph لمتجر إلكتروني. أعد JSON فقط بدون شرح أو markdown أو code fences.'
                : 'You are an e-commerce SEO and Open Graph expert. Return JSON only. No markdown, no code fences, no explanations.';

            $prompt = ($lang === 'ar'
                ? "أنشئ بيانات SEO احترافية ومختصرة لصفحة منتج في متجر إلكتروني.\n"
                : "Generate concise professional SEO data for an e-commerce product page.\n")
                . "\n"
                . "title: {$title}\n"
                . "short_description: {$shortDescription}\n"
                . "description: {$description}\n"
                . "price: {$price}\n"
                . "currency: {$currency}\n"
                . "category: {$category}\n"
                . "featured_image: {$featuredImage}\n\n"
                . ($lang === 'ar'
                    ? "أعد JSON بالمفاتيح التالية فقط:\n"
                    : "Return JSON with these keys only:\n")
                . "meta_title, meta_description, og_title, og_description, og_image, schema_brand, schema_gtin, schema_mpn\n\n"
                . ($lang === 'ar'
                    ? "القواعد:\n- meta_title بين 45 و 70 حرفًا تقريبًا\n- meta_description بين 120 و 160 حرفًا تقريبًا\n- og_title جذاب وقصير\n- og_description واضح وقابل للمشاركة\n- إذا لم تتوفر بيانات مؤكدة لـ schema_brand أو schema_gtin أو schema_mpn فأعدها كسلسلة فارغة\n- استخدم featured_image كما هي داخل og_image إذا كانت موجودة\n- لا تضف أي مفاتيح أخرى\n"
                    : "Rules:\n- meta_title around 45-70 characters\n- meta_description around 120-160 characters\n- og_title should be short and engaging\n- og_description should be clear and shareable\n- If schema_brand or schema_gtin or schema_mpn are unknown, return empty strings\n- Use featured_image as og_image when available\n- Do not add any extra keys\n");

            $raw = $service->generate($prompt, [
                'system'      => $system,
                'max_tokens'  => 500,
                'temperature' => 0.4,
            ]);

            $data = $this->decodeAiJsonObject($raw);
            if (!$data) {
                throw new \Exception(__('products.ai_invalid_seo_response', 'Invalid AI SEO response'));
            }

            $result = [
                'meta_title'       => trim((string)($data['meta_title'] ?? '')),
                'meta_description' => trim((string)($data['meta_description'] ?? '')),
                'og_title'         => trim((string)($data['og_title'] ?? '')),
                'og_description'   => trim((string)($data['og_description'] ?? '')),
                'og_image'         => trim((string)($data['og_image'] ?? '')),
                'schema_brand'     => trim((string)($data['schema_brand'] ?? '')),
                'schema_gtin'      => trim((string)($data['schema_gtin'] ?? '')),
                'schema_mpn'       => trim((string)($data['schema_mpn'] ?? '')),
            ];

            if ($result['meta_title'] === '') {
                $result['meta_title'] = $title;
            }
            if ($result['og_title'] === '') {
                $result['og_title'] = $result['meta_title'];
            }
            if ($result['meta_description'] === '') {
                $result['meta_description'] = mb_substr(strip_tags($shortDescription ?: $description), 0, 160);
            }
            if ($result['og_description'] === '') {
                $result['og_description'] = $result['meta_description'];
            }
            if ($result['og_image'] === '' && $featuredImage !== '') {
                $result['og_image'] = $featuredImage;
            }

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

    private function decodeAiJsonObject(string $raw): ?array
    {
        $raw = trim($raw);
        if ($raw === '') {
            return null;
        }

        $decoded = json_decode($raw, true);
        if (is_array($decoded)) {
            return $decoded;
        }

        $clean = preg_replace('/^```(?:json)?\s*/iu', '', $raw);
        $clean = preg_replace('/\s*```$/u', '', (string)$clean);
        $decoded = json_decode(trim((string)$clean), true);
        if (is_array($decoded)) {
            return $decoded;
        }

        if (preg_match('/\{.*\}/us', $raw, $m)) {
            $decoded = json_decode($m[0], true);
            if (is_array($decoded)) {
                return $decoded;
            }
        }

        return null;
    }

    /* =====================================================
       GENERATE MARKETING MESSAGE (AJAX)
    ===================================================== */
    public function generateMarketingMessage()
    {
        header('Content-Type: application/json');
        try {
            $ctx = [
                'store_name'    => $this->getStoreName(),
                'product'       => trim($_POST['product']       ?? ''),
                'offer'         => trim($_POST['offer']         ?? ''),
                'tone'          => trim($_POST['tone']          ?? 'persuasive'),
                'template_type' => trim($_POST['template_type'] ?? 'offer'),
                'lang'          => trim($_POST['lang']          ?? 'ar'),
                'dialect'       => $this->getDialect(),
                'include_emoji' => ($_POST['emoji'] ?? '1') !== '0',
                'cta'           => trim($_POST['cta']           ?? ''),
            ];

            if (empty($ctx['product'])) {
                throw new \Exception(__('ai.product_required','Product name is required'));
            }

            $service = AiService::fromActiveProvider();
            $message = $this->buildMarketingPrompt($service, $ctx);
            echo json_encode(['success'=>true,'message'=>$message]);

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

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

        try {
            $token = trim((string)($_POST['_csrf'] ?? ''));
            if ($token === '' || empty($_SESSION['_csrf']) || !hash_equals((string)$_SESSION['_csrf'], $token)) {
                $this->jsonResponse([
                    'success' => false,
                    'message' => __('ai.error.csrf', 'Security error'),
                ], 419);
            }

            $productName = trim((string)($_POST['product_name'] ?? ''));
            $productDescription = trim((string)($_POST['product_description'] ?? ''));
            $requestedTypes = $_POST['requested_image_types'] ?? [];
            if (is_string($requestedTypes)) {
                $decodedTypes = json_decode($requestedTypes, true);
                $requestedTypes = is_array($decodedTypes) ? $decodedTypes : [$requestedTypes];
            }
            if (!is_array($requestedTypes)) {
                $requestedTypes = [];
            }

            if ($productName === '') {
                $this->jsonResponse([
                    'success' => false,
                    'message' => __('products.ai_images_name_required', 'Product name is required before generating images.'),
                ], 422);
            }

            $sourceImagePath = '';
            $temporarySourcePath = null;

            if (!empty($_FILES['source_image']['tmp_name'])) {
                $tmp = (string)$_FILES['source_image']['tmp_name'];
                if (!is_uploaded_file($tmp)) {
                    $this->jsonResponse([
                        'success' => false,
                        'message' => __('products.ai_images_source_invalid', 'Unable to validate the source image.'),
                    ], 422);
                }

                $ext = pathinfo((string)($_FILES['source_image']['name'] ?? 'source.png'), PATHINFO_EXTENSION) ?: 'png';
                $temporarySourcePath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'gemini_source_' . bin2hex(random_bytes(8)) . '.' . preg_replace('/[^a-z0-9]+/i', '', $ext);
                if (!@move_uploaded_file($tmp, $temporarySourcePath)) {
                    $this->jsonResponse([
                        'success' => false,
                        'message' => __('products.ai_images_source_invalid', 'Unable to validate the source image.'),
                    ], 422);
                }
                $sourceImagePath = $temporarySourcePath;
            } else {
                $sourceImagePath = trim((string)($_POST['source_image_path'] ?? ''));
            }

            if ($sourceImagePath === '') {
                $this->jsonResponse([
                    'success' => false,
                    'message' => __('products.ai_images_source_required', 'Choose a main product image first.'),
                ], 422);
            }

            $service = new GeminiImageService();
            $uploadService = new UploadService(ROOT_PATH . '/uploads', '/uploads');

            $generated = $service->generateProductImages($sourceImagePath, $productName, $productDescription, array_map('strval', $requestedTypes));
            $stored = [];
            foreach ($generated as $image) {
                $stored[] = [
                    'type' => $image['type'],
                    'label' => $image['label'],
                    'path' => $uploadService->storeBase64Image((string)$image['data'], 'products/generated', 10485760, (string)($image['mime'] ?? 'image/png')),
                ];
            }

            if ($temporarySourcePath && is_file($temporarySourcePath)) {
                @unlink($temporarySourcePath);
            }

            $this->jsonResponse([
                'success' => true,
                'images' => $stored,
                'message' => __('products.ai_images_generated_success', 'Additional images were generated successfully.'),
            ]);
        } catch (\Throwable $e) {
            if (!headers_sent()) {
                $this->jsonResponse([
                    'success' => false,
                    'message' => $e->getMessage(),
                ], 500);
            }
        }
    }

    /* =====================================================
       BUILD MARKETING PROMPT
       الفلسفة: بدلاً من مثال يُقلَّد، نُلزم النموذج
       بكتابة كل سطر بشكل صريح مع البيانات الفعلية
    ===================================================== */
    private function buildMarketingPrompt(AiService $service, array $ctx): string
    {
        $lang         = $ctx['lang']          ?? 'ar';
        $dialect      = $ctx['dialect']       ?? 'fusha';
        $tone         = $ctx['tone']          ?? 'persuasive';
        $emoji        = (bool)($ctx['include_emoji'] ?? true);
        $templateType = $ctx['template_type'] ?? 'offer';
        $product      = trim($ctx['product']  ?? '');
        $offer        = trim($ctx['offer']    ?? '');
        $cta          = trim($ctx['cta']      ?? '');
        $storeName    = $ctx['store_name']    ?? '{store_name}';

        /* ── إيموجي ── */
        $e1 = $emoji ? match($templateType) { 'discount'=>'💰','new_product'=>'🆕',default=>'🔥' } : '';
        $e2 = $emoji ? '📌' : '';
        $e3 = $emoji ? '👇' : '';
        $e4 = $emoji ? '✅' : '';

        /* ── تحية حسب اللهجة ── */
        $greetMap = [
            'algerian' => ['واش راك {name}،','لاباس {name}؟','كيفاش {name}؟'],
            'moroccan' => ['لاباس {name}؟','واش راك {name}؟','كيفاش داير {name}؟'],
            'egyptian' => ['أهلاً {name}!','إزيك {name}؟','عامل إيه {name}؟'],
            'saudi'    => ['هلا {name}!','كيفك {name}؟','وش أخبارك {name}؟'],
            'fusha'    => ['مرحباً {name}،','أهلاً {name}،','السلام عليكم {name}،'],
        ];
        $greetOptions = $lang === 'ar'
            ? ($greetMap[$dialect] ?? $greetMap['fusha'])
            : ['Hey {name}!', 'Hi {name}!', 'Hello {name}!'];

        /* ── Hook متنوع حسب النوع والأسلوب ── */
        $hookPool = $lang === 'ar' ? [
            'offer' => [
                'persuasive' => [
                    "عندك عرض خاص حصري ما تفوتوش {$e1}",
                    "خترنالك عرض ما تشوفوش كل يوم {$e1}",
                    "فرصة ذهبية جات ليك {$e1}",
                    "هاد المرة عندنا شيء خاص بزاف ليك {$e1}",
                ],
                'urgent' => [
                    "عرض محدود ينتهي قريباً {$e1} دابا ولا عمرك!",
                    "آخر فرصة {$e1} العرض ما يبقاش!",
                    "اليوم فقط — عرض ما يتعاودش {$e1}",
                    "المخزون على وشك ينتهي {$e1}",
                ],
                'friendly' => [
                    "كي دير ما ننساكش {$e1} عندنا شيء حلو ليك",
                    "تعرف علاش تواصلنا معاك؟ {$e1} عندنا عرض خاص ليك برك",
                    "صاحبي، هاد المرة جبنالك شيء خاص {$e1}",
                    "ما قدرناش نعديوها بليك {$e1}",
                ],
                'luxury' => [
                    "لأن تستاهل الأحسن {$e1}",
                    "عرض حصري لعملائنا المميزين {$e1}",
                    "تجربة راقية بسعر استثنائي {$e1}",
                ],
            ],
            'discount' => [
                'persuasive' => [
                    "خصم كبير ما تشوفوش كل يوم {$e1}",
                    "وفّر فلوسك اليوم مع عرضنا {$e1}",
                    "أسعار ما تصدقش {$e1}",
                    "العروض هاذي ما تجيش مرتين {$e1}",
                ],
                'urgent' => [
                    "خصم ينتهي اليوم {$e1} دابا!",
                    "آخر ساعات للخصم {$e1}",
                    "العرض محدود — تصرف الآن {$e1}",
                ],
                'friendly' => [
                    "قلتلك هاد الخصم لأنك تستاهل {$e1}",
                    "صاحبي، هاد الخصم خاصك تعرفه {$e1}",
                ],
                'luxury' => [
                    "جودة عالية بسعر استثنائي {$e1}",
                    "تخفيض حصري لعملائنا المميزين {$e1}",
                ],
            ],
            'new_product' => [
                'persuasive' => [
                    "وصلنا بجديد راح يعجبك بزاف {$e1}",
                    "منتج جديد وصل للتو {$e1}",
                    "أول مرة نجيبو هاد المنتج {$e1}",
                    "جديدنا لي كنا منتظرينه {$e1}",
                ],
                'urgent' => [
                    "وصل للتو والمخزون محدود {$e1}",
                    "جديد وصل — كن من الأوائل {$e1}",
                ],
                'friendly' => [
                    "تعرف كيما كنا نقولو؟ وصلنا {$e1}",
                    "جبنا جديد وحسينا بك {$e1}",
                ],
                'luxury' => [
                    "تشكيلتنا الجديدة الحصرية {$e1}",
                    "الجديد اللي كنت تستناه {$e1}",
                ],
            ],
            'custom' => [
                'persuasive' => [
                    "عندنا شيء خاص ليك اليوم {$e1}",
                    "خبر ما تقدرش تفوتو {$e1}",
                    "عندنا خبر حلو ليك {$e1}",
                ],
                'urgent'  => ["دابا أو عمرك {$e1}","الفرصة ما تجيش مرتين {$e1}"],
                'friendly'=> ["صاحبي، سمعلي {$e1}","كي دير ما ننساكش {$e1}"],
                'luxury'  => ["لأن تستاهل الأحسن {$e1}","حصري ليك {$e1}"],
            ],
        ] : [
            'offer'       => ['persuasive'=>["Exclusive offer just for you {$e1}","Special deal you can't miss {$e1}"],'urgent'=>["Limited time offer {$e1}"],'friendly'=>["We thought of you {$e1}"],'luxury'=>["Premium offer for valued customers {$e1}"]],
            'discount'    => ['persuasive'=>["Big savings just for you {$e1}","Unbeatable deal today {$e1}"],'urgent'=>["Discount ends today {$e1}"],'friendly'=>["You deserve this deal {$e1}"],'luxury'=>["Exclusive discount {$e1}"]],
            'new_product' => ['persuasive'=>["Something new you'll love {$e1}","Just arrived — check it out {$e1}"],'urgent'=>["New & limited stock {$e1}"],'friendly'=>["We thought you'd love this {$e1}"],'luxury'=>["Our new exclusive collection {$e1}"]],
            'custom'      => ['persuasive'=>["Something special for you {$e1}"],'urgent'=>["Don't miss this {$e1}"],'friendly'=>["Hey, listen to this {$e1}"],'luxury'=>["Exclusively for you {$e1}"]],
        ];

        // اختيار عشوائي من الـ pool
        $toneKey   = in_array($tone, ['urgent','friendly','luxury']) ? $tone : 'persuasive';
        $typeKey   = array_key_exists($templateType, $hookPool) ? $templateType : 'offer';
        $hookOptions = $hookPool[$typeKey][$toneKey] ?? $hookPool[$typeKey]['persuasive'] ?? ["عرض خاص ليك {$e1}"];
        $greetIdx  = (int)(microtime(true) * 1000) % count($greetOptions);
        $hookIdx   = (int)(microtime(true) * 777)  % count($hookOptions);
        $greeting  = $greetOptions[$greetIdx];
        $hook      = $hookOptions[$hookIdx];

        /* ── CTA ── */
        $ctaFinal = !empty($cta) ? $cta : ($lang === 'ar' ? 'اطلب الآن' : 'Order now');

        /* ── بناء الرسالة الكاملة في PHP ── */
        $lines   = [];
        $lines[] = $greeting;
        $lines[] = $hook;
        $lines[] = ($e2 ? $e2 . ' ' : '') . $product;
        if (!empty($offer)) {
            $lines[] = ($e2 ? $e2 . ' ' : '') . $offer;
        }
        $lines[] = ($e3 ? $e3 . ' ' : '') . $ctaFinal;
        $lines[] = $storeName;

        $baseMessage = implode("
", $lines);

        /* ── نطلب من AI تحسين سطر المنتج فقط (اختياري) ── */
        // نعطيه سطر المنتج الخام ونطلب صياغة أفضل باللهجة
        $dialectNote = $lang === 'ar' ? match($dialect) {
            'algerian' => 'بالجزائري الدارج فقط',
            'moroccan' => 'بالمغربي الدارج فقط',
            'egyptian' => 'بالمصري فقط',
            'saudi'    => 'بالخليجي السعودي فقط',
            default    => 'بالعربية السهلة',
        } : "in natural {$lang}";

        $aiPrompt  = "صِغ هذا السطر {$dialectNote} بطريقة تسويقية مقنعة:
";
        $aiPrompt .= $product . (!empty($offer) ? " — " . $offer : '') . "

";
        $aiPrompt .= "الشروط:
";
        $aiPrompt .= "- سطر واحد فقط
";
        $aiPrompt .= "- لا تحذف اسم المنتج ولا العرض
";
        $aiPrompt .= "- " . ($emoji ? "إيموجي واحد أو اثنين مناسبين" : "بدون إيموجي") . "
";
        $aiPrompt .= "- بدون عنوان أو شرح

";
        $aiPrompt .= "السطر المُحسَّن:";

        try {
            $aiLine = trim($service->generate($aiPrompt, ['max_tokens' => 80, 'temperature' => 0.85]));
            // نتحقق أن النموذج لم يُعد label أو نص فارغ
            $isValid = mb_strlen($aiLine) > 5
                && !str_starts_with($aiLine, 'السطر')
                && !str_starts_with($aiLine, 'Line')
                && !str_starts_with($aiLine, '**')
                && str_contains($aiLine, mb_substr($product, 0, mb_strpos($product . ' ', ' ')));

            if ($isValid) {
                $lines[2] = ($e2 ? $e2 . ' ' : '') . ltrim($aiLine, '📌 ');
                // إذا كان العرض مدمجاً في السطر AI — نحذف السطر المنفصل للعرض
                if (!empty($offer) && str_contains($aiLine, mb_substr($offer, 0, 5))) {
                    unset($lines[3]);
                    $lines = array_values($lines);
                }
            }
        } catch (\Throwable $e) {
            // نُبقي الرسالة PHP كاملة
        }

        return implode("
", $lines);
    }


    /* =====================================================
       HELPERS
    ===================================================== */
    private function loadAllProviders(): array
    {
        $stmt = \db()->query("SELECT * FROM ai_settings ORDER BY id ASC");
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        $out  = ['gemini'=>[],'claude'=>[],'openai'=>[]];
        foreach ($rows as $r) { $out[$r['provider']] = $r; }
        return $out;
    }

    private function getActiveProvider(): string
    {
        $stmt = \db()->query("SELECT provider FROM ai_settings WHERE is_active=1 LIMIT 1");
        return $stmt->fetchColumn() ?: 'gemini';
    }

    private function getDialect(): string
    {
        $stmt = \db()->query("SELECT dialect FROM ai_settings WHERE is_active=1 LIMIT 1");
        return $stmt->fetchColumn() ?: 'fusha';
    }

    private function getStoreName(): string
    {
        try {
            $stmt = \db()->prepare("SELECT setting_value FROM settings WHERE setting_key='site_name' LIMIT 1");
            $stmt->execute();
            return $stmt->fetchColumn() ?: '{store_name}';
        } catch (\Throwable $e) {
            return '{store_name}';
        }
    }

    /* =====================================================
       CLAUDE PROXY — server-side relay (admin AJAX)
       POST /admin/ai/proxy-claude
       Purpose: keeps Claude API key server-side only;
                never exposed to browser JS.
       Body (JSON): {messages, system?, model?, max_tokens?}
    ===================================================== */
    public function proxyClaude(): void
    {
        $this->proxyAssistant();
    }

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

        // Admin session guard — API key must never be accessible without auth
        if (
            empty($_SESSION['admin_logged_in']) ||
            $_SESSION['admin_logged_in'] !== true ||
            empty($_SESSION['admin_id']) ||
            (int)$_SESSION['admin_id'] <= 0
        ) {
            http_response_code(403);
            echo json_encode(['error' => ['type' => 'auth_error', 'message' => 'Unauthorized']]);
            exit;
        }

        // Parse JSON body
        $rawBody = (string)file_get_contents('php://input');
        $body    = json_decode($rawBody, true);
        if (!is_array($body)) {
            http_response_code(400);
            echo json_encode(['error' => ['type' => 'invalid_request_error', 'message' => 'Invalid JSON body']]);
            exit;
        }

        // Retrieve active AI provider configuration from DB
        try {
            $row = AiService::getActiveConfig();
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['error' => ['type' => 'server_error', 'message' => 'Database error']]);
            exit;
        }

        if (!$row || empty($row['api_key'])) {
            http_response_code(422);
            echo json_encode(['error' => ['type' => 'configuration_error', 'message' => 'Active AI provider is not configured']]);
            exit;
        }

        $provider  = (string)($row['provider'] ?? 'gemini');
        $apiKey    = (string)$row['api_key'];
        $model     = (string)($body['model'] ?? $row['model'] ?? 'claude-opus-4-5');
        $maxTokens = min(max((int)($body['max_tokens'] ?? 1024), 1), 8192);
        $messages  = $body['messages'] ?? [];
        $system    = isset($body['system']) && $body['system'] !== '' ? (string)$body['system'] : null;

        if (empty($messages) || !is_array($messages)) {
            http_response_code(400);
            echo json_encode(['error' => ['type' => 'invalid_request_error', 'message' => 'messages array is required']]);
            exit;
        }

        // Sanitize messages: allow only role + content (string or array of blocks)
        $cleanMessages = [];
        foreach ($messages as $msg) {
            if (!is_array($msg) || !isset($msg['role'], $msg['content'])) {
                continue;
            }
            $role = in_array($msg['role'], ['user', 'assistant'], true) ? $msg['role'] : 'user';
            $cleanMessages[] = ['role' => $role, 'content' => $msg['content']];
        }

        if (empty($cleanMessages)) {
            http_response_code(400);
            echo json_encode(['error' => ['type' => 'invalid_request_error', 'message' => 'No valid messages provided']]);
            exit;
        }

        if ($provider === 'claude') {
            $payload = [
                'model'      => $model,
                'max_tokens' => $maxTokens,
                'messages'   => $cleanMessages,
            ];
            if ($system !== null) {
                $payload['system'] = $system;
            }

            $ch = curl_init('https://api.anthropic.com/v1/messages');
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_POST           => true,
                CURLOPT_POSTFIELDS     => json_encode($payload),
                CURLOPT_HTTPHEADER     => [
                    'Content-Type: application/json',
                    'x-api-key: ' . $apiKey,
                    'anthropic-version: 2023-06-01',
                ],
                CURLOPT_SSL_VERIFYPEER => true,
                CURLOPT_SSL_VERIFYHOST => 2,
                CURLOPT_TIMEOUT        => 90,
            ]);

            $response   = curl_exec($ch);
            $httpStatus = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $curlError  = curl_error($ch);
            curl_close($ch);

            if ($response === false || $curlError !== '') {
                http_response_code(502);
                echo json_encode(['error' => ['type' => 'network_error', 'message' => 'Failed to reach Anthropic API: ' . $curlError]]);
                exit;
            }

            http_response_code($httpStatus);
            echo $response;
            exit;
        }

        try {
            $service = new AiService($row);
            $prompt  = $this->buildAssistantPrompt($cleanMessages);
            $text    = $service->generate($prompt, [
                'system'      => $system,
                'max_tokens'  => $maxTokens,
                'temperature' => 0.7,
            ]);

            echo json_encode([
                'id'       => 'assistant_' . bin2hex(random_bytes(6)),
                'provider' => $provider,
                'model'    => $model,
                'content'  => [
                    ['type' => 'text', 'text' => $text],
                ],
            ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            exit;
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['error' => ['type' => 'provider_error', 'message' => $e->getMessage()]]);
            exit;
        }
    }

    private function buildAssistantPrompt(array $messages): string
    {
        $lines = [];
        foreach ($messages as $msg) {
            $role = strtoupper((string)($msg['role'] ?? 'user'));
            $content = $this->flattenAssistantContent($msg['content'] ?? '');
            if ($content === '') {
                continue;
            }
            $lines[] = "[{$role}]\n{$content}";
        }

        $lines[] = '[SYSTEM NOTE] Respond to the latest user request only. If the request asks for HTML, output raw HTML only with no markdown fences.';

        return implode("\n\n", $lines);
    }

    private function flattenAssistantContent(mixed $content): string
    {
        if (is_string($content)) {
            return trim($content);
        }

        if (!is_array($content)) {
            return '';
        }

        $parts = [];
        foreach ($content as $block) {
            if (is_string($block) && trim($block) !== '') {
                $parts[] = trim($block);
                continue;
            }

            if (!is_array($block)) {
                continue;
            }

            $type = (string)($block['type'] ?? '');
            if ($type === 'text' && !empty($block['text'])) {
                $parts[] = trim((string)$block['text']);
            } elseif ($type === 'image') {
                $parts[] = '[User attached an image for context]';
            }
        }

        return trim(implode("\n", $parts));
    }
}
