<?php

namespace Core\App\Controllers;

use Core\App\Models\AiLandingPage;
use Core\App\Models\ProductModel;
use Core\App\Services\AiLandingPageService;
use Core\App\Services\LandingImageAnalysisService;
use Core\App\Services\LandingPageAgentService;
use Core\App\Services\LandingStructureBuilder;
use Core\App\Services\UploadService;
use Core\System\Csrf;
use Core\System\Env;
use Core\System\HtmlSanitizer;
use Core\System\Response;

class AiLandingPageController
{
    private AiLandingPage $model;
    private ProductModel  $products;

    public function __construct()
    {
        $this->model    = new AiLandingPage();
        $this->products = new ProductModel();
    }

    /* =====================================================
       INDEX — list all landing pages
    ===================================================== */
    public function index(): void
    {
        $pages = $this->model->getAll();

        view_admin('ai_landing_pages/index', [
            'pages' => $pages,
        ]);
    }

    /* =====================================================
       CREATE FORM
    ===================================================== */
    public function create(): void
    {
        $products = $this->products->getAll();
        $presetMode = $_GET['mode'] ?? 'manual';

        view_admin('ai_landing_pages/create', [
            'products'     => $products,
            'page'         => null,
            'conversation' => [],
            'presetMode'   => in_array($presetMode, ['manual', 'image'], true) ? $presetMode : 'manual',
        ]);
    }

    /* =====================================================
       STORE — save a new landing page (name + product only)
    ===================================================== */
    public function store(): void
    {
        Csrf::check();

        $productId = (int)($_POST['product_id'] ?? 0);
        $name      = trim($_POST['name'] ?? '');
        $slug      = trim($_POST['slug'] ?? '');
        $sourceMode = $_POST['source_mode'] ?? 'manual';

        if ($productId <= 0 || $name === '') {
            $_SESSION['lp_error'] = __('landing.error_required', 'Product and name are required.');
            Response::redirect('/admin/ai-landing-pages/create');
        }

        if ($slug === '') {
            $slug = $name;
        }

        $id = $this->model->create([
            'product_id'   => $productId,
            'name'         => $name,
            'slug'         => $slug,
            'html_content' => '',
            'conversation' => [],
            'status'       => 'draft',
            'source_mode'  => in_array($sourceMode, ['manual', 'image'], true) ? $sourceMode : 'manual',
        ]);

        if ($sourceMode === 'image' && !empty($_FILES['source_image']['tmp_name'])) {
            try {
                $upload = new UploadService(ROOT_PATH . '/uploads', '/uploads');
                $sourceImage = $upload->storeImage($_FILES['source_image'], 'landing-pages/source-images');
                $this->model->update($id, [
                    'source_mode' => 'image',
                    'source_image' => $sourceImage,
                ]);
                $_SESSION['lp_success'] = __('landing.image_pipeline_queued', 'The image was saved. The analysis will start inside the builder.');
            } catch (\Throwable $e) {
                $_SESSION['lp_error'] = $e->getMessage();
            }
        }

        Response::redirect('/admin/ai-landing-pages/edit/' . $id);
    }

    /* =====================================================
       EDIT FORM — landing page builder UI
    ===================================================== */
    public function edit(int $id): void
    {
        $page = $this->model->getById($id);

        if (!$page) {
            Response::redirect('/admin/ai-landing-pages');
        }

        $products     = $this->products->getAll();
        $product      = $this->products->getById((int)$page['product_id']);
        $productPages = $this->model->getByProduct((int)$page['product_id']);
        $conversation = $page['conversation'] ?? [];
        $success      = $_SESSION['lp_success'] ?? null;
        $error        = $_SESSION['lp_error'] ?? null;
        if ($success) unset($_SESSION['lp_success']);
        if ($error) unset($_SESSION['lp_error']);

        // Render as standalone full-page builder (edit.php has its own <html> wrapper)
        // Do NOT use view_admin() which wraps with admin header/footer causing nested HTML
        extract([
            'page'         => $page,
            'products'     => $products,
            'product'      => $product,
            'productPages' => $productPages,
            'conversation' => $conversation,
            'success'      => $success,
            'error'        => $error,
        ]);
        require ROOT_PATH . '/admin/templates/ai_landing_pages/studio.php';
        exit;
    }

    public function chatExpert(int $id): void
    {
        $page = $this->model->getById($id);

        if (!$page) {
            Response::redirect('/admin/ai-landing-pages');
        }

        $product = $this->products->getById((int)$page['product_id']);
        $productPages = $this->model->getByProduct((int)$page['product_id']);
        $conversation = is_array($page['conversation'] ?? null) ? $page['conversation'] : [];
        $agent = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
        $workspace = is_array($agent['workspace'] ?? null) ? $agent['workspace'] : [];
        $sessionHistory = is_array($workspace['session_history'] ?? null) ? $workspace['session_history'] : [];
        $tasks = is_array($workspace['tasks'] ?? null) ? $workspace['tasks'] : [];
        $briefs = is_array($agent['brief_history'] ?? null) && !empty($agent['brief_history'])
            ? $agent['brief_history']
            : (is_array($agent['briefs'] ?? null) ? $agent['briefs'] : []);
        $success = $_SESSION['lp_success'] ?? null;
        $error = $_SESSION['lp_error'] ?? null;
        if ($success) {
            unset($_SESSION['lp_success']);
        }
        if ($error) {
            unset($_SESSION['lp_error']);
        }

        extract([
            'page' => $page,
            'product' => $product,
            'productPages' => $productPages,
            'conversation' => $conversation,
            'agent' => $agent,
            'workspace' => $workspace,
            'sessionHistory' => $sessionHistory,
            'tasks' => $tasks,
            'briefs' => $briefs,
            'success' => $success,
            'error' => $error,
        ]);

        require ROOT_PATH . '/admin/templates/ai_landing_pages/chat_expert.php';
        exit;
    }

    public function createSession(int $id): void
    {
        Csrf::check();

        $page = $this->model->getById($id);
        if (!$page) {
            $_SESSION['lp_error'] = __('landing.session_create_failed', 'تعذر إنشاء جلسة جديدة.');
            Response::redirect('/admin/ai-landing-pages');
        }

        $product = $this->products->getById((int)$page['product_id']);
        $baseName = trim((string)($page['name'] ?? ($product['title'] ?? __('landing.product', 'المنتج'))));
        $timestamp = date('Ymd-His');
        $newName = $baseName . ' - ' . __('landing.session_copy_suffix', 'جلسة') . ' ' . $timestamp;
        $newSlug = trim((string)($page['slug'] ?? 'landing-page')) . '-session-' . date('His');

        $agentTrace = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
        $workspace = is_array($agentTrace['workspace'] ?? null) ? $agentTrace['workspace'] : [];
        $workspace['session_title'] = $newName;
        $workspace['current_objective'] = (string)($workspace['current_objective'] ?? __('landing.session_default_objective', 'إدارة جلسة مستقلة للمحادثة والإنتاج.'));
        $workspace['session_history'] = [[
            'id' => 'session_' . substr(md5($newName . microtime(true)), 0, 10),
            'title' => __('landing.session_created_title', 'تم إنشاء جلسة جديدة'),
            'summary' => __('landing.session_created_text', 'هذه الجلسة بدأت كنسخة مستقلة من الجلسة الحالية ويمكن تطويرها بشكل منفصل.'),
            'stage' => 'session',
            'at' => gmdate('c'),
            'metrics' => [
                'sections' => count(is_array($agentTrace['sections'] ?? null) ? $agentTrace['sections'] : []),
                'concepts' => count(is_array($agentTrace['concepts'] ?? null) ? $agentTrace['concepts'] : []),
                'briefs' => count(is_array($agentTrace['brief_history'] ?? null) ? $agentTrace['brief_history'] : []),
                'variants' => count(is_array($agentTrace['variants'] ?? null) ? $agentTrace['variants'] : []),
            ],
        ]];
        $agentTrace['workspace'] = $workspace;
        $agentTrace['history'] = $this->appendAgentHistory(
            is_array($agentTrace['history'] ?? null) ? $agentTrace['history'] : [],
            'session_created',
            __('landing.session_created_log', 'تم إنشاء جلسة مستقلة جديدة من الجلسة الأصلية.')
        );

        $conversation = is_array($page['conversation'] ?? null) ? $page['conversation'] : [];
        array_unshift($conversation, [
            'role' => 'system',
            'content' => __('landing.session_created_text', 'هذه الجلسة بدأت كنسخة مستقلة من الجلسة الحالية ويمكن تطويرها بشكل منفصل.'),
        ]);

        $newId = $this->model->create([
            'product_id' => (int)$page['product_id'],
            'name' => $newName,
            'slug' => $newSlug,
            'html_content' => (string)($page['html_content'] ?? ''),
            'conversation' => $conversation,
            'status' => 'draft',
            'source_mode' => (string)($page['source_mode'] ?? 'manual'),
            'source_image' => (string)($page['source_image'] ?? ''),
            'analysis_json' => is_array($page['analysis_json'] ?? null) ? $page['analysis_json'] : [],
            'structure_json' => is_array($page['structure_json'] ?? null) ? $page['structure_json'] : [],
            'agent_trace' => $agentTrace,
        ]);

        $_SESSION['lp_success'] = __('landing.session_created_success', 'تم إنشاء جلسة جديدة بنجاح.');
        Response::redirect('/admin/ai-landing-pages/chat/' . $newId);
    }

    public function destinationWorkspace(int $id, string $destination): void
    {
        $page = $this->model->getById($id);
        if (!$page) {
            Response::redirect('/admin/ai-landing-pages');
        }

        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            Response::redirect('/admin/ai-landing-pages/edit/' . $id);
        }

        $destination = $this->normalizeDestination($destination);
        $productPages = $this->model->getByProduct((int)$page['product_id']);
        $agent = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
        $agent = $this->ensureDestinationWorkflows($agent, $page, $product);
        $workflows = is_array($agent['destination_workflows'] ?? null) ? $agent['destination_workflows'] : [];
        $workflow = is_array($workflows[$destination] ?? null) ? $workflows[$destination] : [];

        $this->model->update($id, ['agent_trace' => $agent]);

        $success = $_SESSION['lp_success'] ?? null;
        $error = $_SESSION['lp_error'] ?? null;
        if ($success) {
            unset($_SESSION['lp_success']);
        }
        if ($error) {
            unset($_SESSION['lp_error']);
        }

        extract([
            'page' => $page,
            'product' => $product,
            'productPages' => $productPages,
            'agent' => $agent,
            'workflow' => $workflow,
            'destination' => $destination,
            'success' => $success,
            'error' => $error,
        ]);

        require ROOT_PATH . '/admin/templates/ai_landing_pages/destination_workflow.php';
        exit;
    }

    public function runDestinationWorkflow(int $id, string $destination): void
    {
        header('Content-Type: application/json; charset=utf-8');
        Csrf::check();

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            echo json_encode(['success' => false, 'error' => __('landing.product_missing', 'المنتج غير موجود.')]);
            exit;
        }

        $destination = $this->normalizeDestination($destination);
        $agent = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
        $agent = $this->ensureDestinationWorkflows($agent, $page, $product);
        $workflow = is_array(($agent['destination_workflows'] ?? [])[$destination] ?? null)
            ? $agent['destination_workflows'][$destination]
            : [];

        $artifact = $this->buildDestinationArtifact($destination, $page, $product, $agent, $workflow);
        $workflow['artifact'] = $artifact;
        $workflow['status'] = 'done';
        $workflow['current_stage'] = 'review';
        $workflow['run_count'] = (int)($workflow['run_count'] ?? 0) + 1;
        $workflow['updated_at'] = gmdate('c');
        $workflow['history'] = is_array($workflow['history'] ?? null) ? $workflow['history'] : [];
        $workflow['history'][] = [
            'id' => 'workflow_' . substr(md5($destination . microtime(true)), 0, 10),
            'title' => __('landing.workflow_run_entry', 'تم تشغيل الـ workflow'),
            'summary' => __('landing.workflow_run_entry_text', 'تم إنتاج مخرجات جديدة لهذه الوجهة وحفظها داخل الجلسة الحالية.'),
            'at' => gmdate('c'),
            'stage' => 'review',
        ];
        $workflow['history'] = array_slice($workflow['history'], -16);

        $stages = is_array($workflow['stages'] ?? null) ? $workflow['stages'] : [];
        foreach ($stages as &$stage) {
            $stageId = (string)($stage['id'] ?? '');
            $stage['status'] = in_array($stageId, ['analysis', 'brief', 'production', 'review'], true)
                ? ($stageId === 'review' ? 'done' : 'done')
                : 'done';
        }
        unset($stage);
        $workflow['stages'] = $stages;

        $agent['destination_workflows'][$destination] = $workflow;
        $agent['history'] = $this->appendAgentHistory(
            is_array($agent['history'] ?? null) ? $agent['history'] : [],
            'destination_workflow_run',
            __('landing.workflow_run_log', 'تم تشغيل workflow مستقل لإحدى وجهات الإنتاج.'),
            ['destination' => $destination]
        );
        $agent = $this->appendSessionSnapshot(
            $agent,
            __('landing.workflow_snapshot_title', 'تشغيل Workflow مستقل'),
            __('landing.workflow_snapshot_text', 'تم إنتاج مخرجات تنفيذية مستقلة لإحدى الوجهات داخل نفس الجلسة.'),
            'workflow'
        );

        $conversation = is_array($page['conversation'] ?? null) ? $page['conversation'] : [];
        $conversation[] = [
            'role' => 'assistant',
            'content' => ($workflow['title'] ?? $destination) . "\n" . ($artifact['summary'] ?? ''),
        ];

        $this->model->update($id, [
            'agent_trace' => $agent,
            'conversation' => $conversation,
        ]);

        echo json_encode([
            'success' => true,
            'workflow' => $workflow,
            'agent' => $agent,
            'conversation' => $conversation,
            'message' => __('landing.workflow_run_success', 'تم تشغيل الـ workflow بنجاح.'),
        ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

    /* =====================================================
       UPDATE — save meta fields (name, slug, status)
    ===================================================== */
    public function update(int $id): void
    {
        Csrf::check();

        $page = $this->model->getById($id);
        if (!$page) {
            Response::redirect('/admin/ai-landing-pages');
        }

        $this->model->update($id, [
            'product_id' => (int)($_POST['product_id'] ?? $page['product_id']),
            'name'       => trim($_POST['name'] ?? $page['name']),
            'slug'       => trim($_POST['slug'] ?? $page['slug']),
            'status'     => $_POST['status'] ?? $page['status'],
        ]);

        $_SESSION['lp_success'] = __('landing.saved', 'Landing page saved.');
        Response::redirect('/admin/ai-landing-pages/edit/' . $id);
    }

    /* =====================================================
       DELETE
    ===================================================== */
    public function delete(int $id): void
    {
        Csrf::check();
        $this->model->delete($id);
        $_SESSION['lp_success'] = __('landing.deleted', 'Landing page deleted.');
        Response::redirect('/admin/ai-landing-pages');
    }

    /* =====================================================
       AJAX — Generate / update HTML via AI
       POST /admin/ai-landing-pages/generate/{id}
    ===================================================== */
    public function generate(int $id): void
    {
        header('Content-Type: application/json; charset=utf-8');

        \Core\System\Csrf::check();

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        $userMessage = trim((string)($_POST['message'] ?? ''));
        if ($userMessage === '') {
            echo json_encode(['success' => false, 'error' => __('lp.message_required', 'Message is required.')]);
            exit;
        }

        // Append user message to conversation
        $conversation   = $page['conversation'] ?? [];
        $conversation[] = ['role' => 'user', 'content' => $userMessage];

        // Get current product data
        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            echo json_encode(['success' => false, 'error' => 'Product not found']);
            exit;
        }

        $quickHtml = $this->applyQuickStudioEdits((string)($page['html_content'] ?? ''), $userMessage, $product, $page);
        if ($quickHtml !== null) {
            $conversation[] = [
                'role'    => 'assistant',
                'content' => __('landing.ai_updated', 'تم تحديث الصفحة بناءً على طلبك.'),
            ];

            $quickHtml = $this->sanitizeImportedHtml($quickHtml);
            $this->model->update($id, [
                'html_content' => $quickHtml,
                'conversation' => $conversation,
            ]);

            echo json_encode([
                'success' => true,
                'html'    => $quickHtml,
                'mode'    => 'quick_edit',
            ]);
            exit;
        }

        // Call AI service
        try {
            $service  = new AiLandingPageService();
            $newHtml  = $service->generateFromConversation(
                $product,
                $conversation,
                $page['html_content'] ?: null
            );
        } catch (\Throwable $e) {
            echo json_encode([
                'success' => false,
                'error'   => $e->getMessage(),
            ]);
            exit;
        }

        // Append assistant response to conversation (summarise, not full HTML)
        $conversation[] = [
            'role'    => 'assistant',
            'content' => __('landing.ai_updated', 'I\'ve updated the landing page based on your request.'),
        ];

        // Sanitize AI-generated HTML before storing — prevent Stored XSS
        // Use lightweight sanitization that keeps <style> and layout structure intact
        $newHtml = $this->sanitizeImportedHtml($newHtml);

        // Persist to DB
        $this->model->update($id, [
            'html_content' => $newHtml,
            'conversation' => $conversation,
        ]);

        echo json_encode([
            'success' => true,
            'html'    => $newHtml,
        ]);
        exit;
    }

    /* =====================================================
       AJAX — Save HTML directly (manual edit / paste)
       POST /admin/ai-landing-pages/save-html/{id}
    ===================================================== */
    public function saveHtml(int $id): void
    {
        header('Content-Type: application/json; charset=utf-8');

        \Core\System\Csrf::check();

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        // Sanitize before storing — prevents Stored XSS even if preview serves raw
        $html = HtmlSanitizer::sanitize($_POST['html'] ?? '');

        $this->model->update($id, ['html_content' => $html]);

        echo json_encode(['success' => true]);
        exit;
    }

    /* =====================================================
       PREVIEW — render landing page in iframe
       GET /admin/ai-landing-pages/preview/{id}
    ===================================================== */
    public function preview(int $id): void
    {
        $page = $this->model->getById($id);

        if (!$page || empty($page['html_content'])) {
            http_response_code(404);
            $msgNoContent = htmlspecialchars(__('lp.preview_no_content', 'No content yet. Use the builder to generate a landing page first.'), ENT_QUOTES, 'UTF-8');
            echo '<!DOCTYPE html><html><body style="font-family:sans-serif;padding:40px;text-align:center">'
               . '<h2>' . $msgNoContent . '</h2>'
               . '</body></html>';
            exit;
        }

        header('Content-Type: text/html; charset=utf-8');
        header('X-Frame-Options: SAMEORIGIN');
        header("Content-Security-Policy: default-src 'self'; script-src 'unsafe-inline' https:; style-src 'unsafe-inline' https:; img-src * data:; font-src * data:; media-src * data:; frame-src * data:; connect-src *; frame-ancestors 'self'");

        // Replace {{ORDER_FORM}} so the preview renders the actual iframe instead of the raw placeholder
        $html      = $page['html_content'];
        $productId = (int)($page['product_id'] ?? 0);
        $baseUrl   = rtrim(\Core\System\Env::get('APP_URL', ''), '/');
        if ($baseUrl === '') {
            $scheme  = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
            $host    = $_SERVER['HTTP_HOST'] ?? 'localhost';
            $baseUrl = $scheme . '://' . $host;
        }
        $html = str_replace(
            ['{{ORDER_FORM}}', '{{PRODUCT_ID}}', '{{ORDER_URL}}'],
            [$baseUrl . '/lp-order-form/' . $productId, (string)$productId, $baseUrl . '/product/' . $productId],
            $html
        );

        // Use lightweight sanitization that strips scripts/event-handlers but keeps
        // <style> blocks and the full HTML structure so the preview renders correctly.
        echo $this->sanitizeImportedHtml($html);
        exit;
    }

    /* =====================================================
       PUBLIC VIEW — show published landing page
       GET /lp/{slug}
    ===================================================== */
    public function publicView(string $slug): void
    {
        $page = $this->model->getBySlug($slug);

        if (!$page || empty($page['html_content'])) {
            http_response_code(404);
            $msg404 = htmlspecialchars(__('lp.page_not_found', '404 — Page not found'), ENT_QUOTES, 'UTF-8');
            echo '<!DOCTYPE html><html><body style="font-family:sans-serif;padding:40px;text-align:center">'
               . '<h2>' . $msg404 . '</h2></body></html>';
            exit;
        }

        // ── Step 1: extract <style> CSS before HtmlSanitizer strips it ──────────
        $cssContent = '';
        $rawHtml = $page['html_content'];

        $htmlNoCss = preg_replace_callback(
            '/<style\b[^>]*>(.*?)<\/style>/is',
            function (array $m) use (&$cssContent): string {
                $css = $m[1];
                // CSS-specific sanitization: block dangerous patterns
                $css = preg_replace('/expression\s*\(/i', '', $css);
                $css = preg_replace('/javascript\s*:/i', '', $css);
                $css = preg_replace('/vbscript\s*:/i', '', $css);
                $css = preg_replace('/url\s*\(\s*["\']?\s*(javascript|vbscript|data):[^)]*\)/i', '', $css);
                $css = preg_replace('/-moz-binding\s*:/i', '', $css);
                $cssContent .= "\n" . $css;
                return '';
            },
            $rawHtml
        ) ?? $rawHtml;

        // ── Step 2: extract safe external <link rel="stylesheet"> (Google Fonts, CDN) ──
        $linkTags = '';
        $htmlNoLinks = preg_replace_callback(
            '/<link\b[^>]*\/?>/is',
            function (array $m) use (&$linkTags): string {
                $tag = $m[0];
                if (preg_match('/rel\s*=\s*["\']stylesheet["\']/i', $tag)
                    && preg_match('/href\s*=\s*["\']https:\/\//i', $tag)) {
                    $linkTags .= "\n" . $tag;
                }
                return '';
            },
            $htmlNoCss
        ) ?? $htmlNoCss;

        // ── Step 3: sanitize remaining HTML (removes scripts/event handlers) ──────
        $html = HtmlSanitizer::sanitize($htmlNoLinks);
        $productId = (int)$page['product_id'];

        // ── SEO: build canonical URL, page title, description and images ──
        $pageSlug  = (string)($page['slug'] ?? '');
        $pageTitle = htmlspecialchars(strip_tags((string)($page['name'] ?? '')), ENT_QUOTES, 'UTF-8');

        // Build base URL: prefer APP_URL from .env, fall back to current request origin
        // so canonical is always absolute even if the admin forgot to set APP_URL.
        $appUrl  = \Core\System\Env::get('APP_URL', '');
        if ($appUrl !== '') {
            $baseUrl = rtrim($appUrl, '/');
        } else {
            $scheme  = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
            // Use SERVER_NAME (server config) not HTTP_HOST (user-controlled) as last resort
            $host    = (string)($_SERVER['SERVER_NAME'] ?? 'localhost');
            $baseUrl = $scheme . '://' . $host;
        }
        $canonical = $baseUrl . '/lp/' . rawurlencode($pageSlug);

        // Dynamic language and direction from the active site language
        $langCode = htmlspecialchars(\Core\System\Language::code(), ENT_QUOTES, 'UTF-8');
        $langDir  = htmlspecialchars(\Core\System\Language::direction(), ENT_QUOTES, 'UTF-8');

        // Pull SEO fields from the linked product (og_description, og_image, meta_description)
        $seoDescription = $pageTitle; // fallback: page name
        $ogImage        = '';
        if ($productId > 0) {
            $product = $this->products->getById($productId);
            if ($product) {
                $rawDesc = $product['og_description']
                    ?? $product['meta_description']
                    ?? $product['description']
                    ?? '';
                if (trim(strip_tags($rawDesc)) !== '') {
                    $seoDescription = htmlspecialchars(
                        mb_substr(strip_tags($rawDesc), 0, 160),
                        ENT_QUOTES,
                        'UTF-8'
                    );
                }
                $rawImg = $product['og_image'] ?? $product['featured_image'] ?? '';
                if ($rawImg !== '') {
                    $ogImage = strpos($rawImg, 'http') === 0
                        ? htmlspecialchars($rawImg, ENT_QUOTES, 'UTF-8')
                        : htmlspecialchars($baseUrl . '/' . ltrim($rawImg, '/'), ENT_QUOTES, 'UTF-8');
                }
            }
        }

        // Build image meta tags conditionally
        $ogImageTag      = $ogImage !== '' ? "\n<meta property=\"og:image\" content=\"{$ogImage}\">" : '';
        $twitterImageTag = $ogImage !== '' ? "\n<meta name=\"twitter:image\" content=\"{$ogImage}\">" : '';

        $seoHead = <<<HTML
<!DOCTYPE html>
<html dir="{$langDir}" lang="{$langCode}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{$pageTitle}</title>
<meta name="description" content="{$seoDescription}">
<link rel="canonical" href="{$canonical}">
<meta property="og:title" content="{$pageTitle}">
<meta property="og:description" content="{$seoDescription}">
<meta property="og:url" content="{$canonical}">
<meta property="og:type" content="website">{$ogImageTag}
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{$pageTitle}">
<meta name="twitter:description" content="{$seoDescription}">{$twitterImageTag}
<meta name="robots" content="index, follow">
</head>
<body>
HTML;
        // ─────────────────────────────────────────────────────────────────

        // Inject order tracking script so order buttons on the page can submit orders
        // Replace placeholder {{ORDER_FORM}} with the product order URL
        $lpOrderBase = $baseUrl . '/lp-order-form/';
        $productBase = $baseUrl . '/product/';

        $html = str_replace(
            ['{{ORDER_FORM}}', '{{PRODUCT_ID}}', '{{ORDER_URL}}'],
            [
                $lpOrderBase . $productId,
                (string)$productId,
                $productBase . $productId,
            ],
            $html
        );

        // Fix iframe sandbox attributes for order form iframes
        $html = preg_replace(
            '/<iframe([^>]+src=["\'][^"\']*)(\/lp-order-form\/[0-9]+[^"\']*)(["\'][^>]*>)/i',
            '<iframe$1$2$3',
            $html
        );

        // Inject a helper script so landing page order buttons target the embedded order form first
        $orderScript = <<<JS
<script>
(function(){
    function getOrderTarget(){
        return document.querySelector('#lp-order-section')
            || document.querySelector('[data-lp-order-frame]')
            || document.querySelector('iframe[src*="/lp-order-form/"]');
    }

    document.querySelectorAll('[data-lp-order],[href="#order"],[href="#طلب"]').forEach(function(el){
        el.addEventListener('click', function(e){
            var target = getOrderTarget();
            if (target) {
                e.preventDefault();
                target.scrollIntoView({behavior:'smooth', block:'start'});
                try {
                    if (target.tagName === 'IFRAME') {
                        target.contentWindow && target.contentWindow.focus && target.contentWindow.focus();
                    } else {
                        var iframe = target.querySelector('iframe');
                        iframe && iframe.contentWindow && iframe.contentWindow.focus && iframe.contentWindow.focus();
                    }
                } catch (err) {}
                return;
            }
            e.preventDefault();
            window.location.href = '/product/{$productId}';
        });
    });
})();
</script>
JS;
        // ── Step 4: extract body content only ──────────────────────────────────
        $html = preg_replace('/^[\s\S]*?<body[^>]*>/i', '', $html);
        $html = preg_replace('/<\/body>[\s\S]*$/i', '', $html);

        // ── Step 5: inject extracted CSS + external links into <head> ───────────
        $headInjection = $linkTags;
        if (trim($cssContent) !== '') {
            $headInjection .= "\n<style>" . $cssContent . "\n</style>";
        }
        if ($headInjection !== '') {
            $seoHead = str_replace('</head>', $headInjection . "\n</head>", $seoHead);
        }

        // Wrap in proper SEO document
        $fullPage = $seoHead . "\n" . $html . "\n" . $orderScript . "\n</body>\n</html>";

        header('Content-Type: text/html; charset=utf-8');
        echo $fullPage;
        exit;
    }

    /* =====================================================
       AJAX — Upload image for use in landing page
       POST /admin/ai-landing-pages/upload-image/{id}
    ===================================================== */
    public function uploadImage(int $id): void
    {
        header('Content-Type: application/json; charset=utf-8');
        Csrf::check();

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        if (empty($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
            echo json_encode(['success' => false, 'error' => __('lp.no_image_uploaded', 'No image uploaded.')]);
            exit;
        }

        try {
            $upload  = new \Core\App\Services\UploadService(
                ROOT_PATH . '/uploads',
                '/uploads'
            );
            $webPath = $upload->storeImage($_FILES['image'], 'landing-pages');
            // Use APP_URL from .env to avoid HTTP_HOST header injection
            $appBase = rtrim(\Core\System\Env::get('APP_URL', ''), '/');
            $fullUrl = $appBase !== '' ? $appBase . $webPath : $webPath;

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

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

        try {
            $result = $this->runImagePipeline($id, $_FILES['source_image'] ?? null);
            echo json_encode([
                'success' => true,
                'html' => $result['html'],
                'analysis' => $result['analysis'],
                'structure' => $result['structure'],
                'agent' => $result['agent_trace'],
                'sourceImage' => $result['source_image'],
            ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        } catch (\Throwable $e) {
            http_response_code(422);
            echo json_encode(['success' => false, 'error' => $e->getMessage()]);
        }
        exit;
    }

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

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            echo json_encode(['success' => false, 'error' => __('landing.product_missing', 'Product not found')]);
            exit;
        }

        $structure = $page['structure_json'] ?? [];
        if (empty($structure)) {
            echo json_encode(['success' => false, 'error' => __('landing.structure_missing', 'No image-derived structure found for this page.')]);
            exit;
        }

        try {
            $agent = new LandingPageAgentService();
            $result = $agent->buildFromStructure($product, $structure, $page['html_content'] ?? null);

            $conversation = $page['conversation'] ?? [];
            $conversation[] = [
                'role' => 'assistant',
                'content' => __('landing.regenerated_note', 'The AI agent regenerated and improved the landing page from the saved image structure.'),
            ];

            $html = $this->sanitizeImportedHtml($result['html']);
            $result = $this->appendSessionSnapshot(
                is_array($result) ? $result : [],
                'إعادة توليد الصفحة',
                'تمت إعادة بناء الصفحة من الـ structure المحفوظ.',
                'regenerate'
            );

            $this->model->update($id, [
                'html_content' => $html,
                'agent_trace' => $result,
                'conversation' => $conversation,
            ]);

            echo json_encode([
                'success' => true,
                'html' => $html,
                'agent' => $result,
                'structure' => $structure,
            ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        } catch (\Throwable $e) {
            http_response_code(422);
            echo json_encode(['success' => false, 'error' => $e->getMessage()]);
        }
        exit;
    }

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

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            echo json_encode(['success' => false, 'error' => __('landing.product_missing', 'Product not found')]);
            exit;
        }

        $structureRaw = (string)($_POST['structure_json'] ?? '');
        $selectedConcept = trim((string)($_POST['selected_concept'] ?? ''));
        $structure = json_decode($structureRaw, true);

        if (!is_array($structure) || empty($structure['sections'])) {
            echo json_encode(['success' => false, 'error' => __('landing.structure_missing', 'No image-derived structure found for this page.')]);
            exit;
        }

        $structure['sections'] = array_values(array_filter($structure['sections'], static function ($section) {
            return is_array($section) && (($section['enabled'] ?? true) !== false);
        }));

        try {
            $agent = new LandingPageAgentService();
            $result = $agent->buildFromStructure($product, $structure, $page['html_content'] ?? null, [
                'selected_concept' => $selectedConcept,
            ]);

            $html = $this->sanitizeImportedHtml($result['html']);
            $conversation = $page['conversation'] ?? [];
            $conversation[] = [
                'role' => 'assistant',
                'content' => __('landing.assembled_note', 'The landing page was assembled from your selected concept and edited sections.'),
            ];

            $result = $this->appendSessionSnapshot(
                is_array($result) ? $result : [],
                'تجميع الصفحة',
                'تم تجميع الأقسام المختارة داخل نسخة نهائية جديدة.',
                'assemble'
            );

            $this->model->update($id, [
                'structure_json' => $structure,
                'agent_trace' => $result,
                'html_content' => $html,
                'conversation' => $conversation,
            ]);

            echo json_encode([
                'success' => true,
                'html' => $html,
                'structure' => $structure,
                'agent' => $result,
            ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        } catch (\Throwable $e) {
            http_response_code(422);
            echo json_encode(['success' => false, 'error' => $e->getMessage()]);
        }
        exit;
    }

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

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            echo json_encode(['success' => false, 'error' => __('landing.product_missing', 'Product not found')]);
            exit;
        }

        $structure = $page['structure_json'] ?? [];
        if (empty($structure['sections'])) {
            echo json_encode(['success' => false, 'error' => __('landing.structure_missing', 'No image-derived structure found for this page.')]);
            exit;
        }

        try {
            $result = $this->buildFastVariants($page, $product, $structure);

            $agentTrace = $page['agent_trace'] ?? [];
            $agentTrace['variants'] = $result['variants'] ?? [];
            $agentTrace = $this->appendSessionSnapshot(
                is_array($agentTrace) ? $agentTrace : [],
                'توليد Variants',
                'تم توليد مجموعة جديدة من النسخ البديلة للصفحة الحالية.',
                'variants'
            );

            $this->model->update($id, [
                'agent_trace' => $agentTrace,
            ]);

            echo json_encode([
                'success' => true,
                'variants' => $result['variants'] ?? [],
            ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        } catch (\Throwable $e) {
            http_response_code(422);
            echo json_encode(['success' => false, 'error' => $e->getMessage()]);
        }
        exit;
    }

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

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            echo json_encode(['success' => false, 'error' => __('landing.product_missing', 'Product not found')]);
            exit;
        }

        $url = trim((string)($_POST['url'] ?? ''));
        if ($url === '' || !filter_var($url, FILTER_VALIDATE_URL)) {
            echo json_encode(['success' => false, 'error' => __('landing.competitor_invalid_url', 'Please enter a valid competitor URL.')]);
            exit;
        }

        try {
            $html = $this->fetchCompetitorHtml($url);
            $agent = new LandingPageAgentService();
            $report = $agent->analyzeCompetitor($product, $url, $html);
            $agentTrace = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
            $report = $this->expandCompetitorReport($report, $page, $product, $agentTrace, $url);
            $history = is_array($agentTrace['competitor_history'] ?? null) ? $agentTrace['competitor_history'] : [];
            $entry = [
                'id' => 'comp_' . substr(md5($url . microtime(true)), 0, 10),
                'url' => $url,
                'domain' => parse_url($url, PHP_URL_HOST) ?: $url,
                'report' => $report,
                'at' => gmdate('c'),
            ];
            $history[] = $entry;
            $agentTrace['competitor_report'] = $report;
            $agentTrace['competitor_analysis'] = $report;
            $agentTrace['competitor_history'] = array_slice($history, -8);
            $agentTrace['history'] = $this->appendAgentHistory(
                is_array($agentTrace['history'] ?? null) ? $agentTrace['history'] : [],
                'competitor_analyzed',
                'تم تحليل منافس جديد واستخراج الفجوات التسويقية.',
                ['url' => $url]
            );
            $agentTrace = $this->appendSessionSnapshot(
                $agentTrace,
                'تحليل منافس',
                'تم تحليل المنافس ' . ($entry['domain'] ?? $url) . ' وإضافة تقرير جديد إلى الأرشيف.',
                'competitor'
            );
            $this->model->update($id, ['agent_trace' => $agentTrace]);

            echo json_encode([
                'success' => true,
                'report' => $report,
                'agent' => $agentTrace,
            ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        } catch (\Throwable $e) {
            http_response_code(422);
            echo json_encode(['success' => false, 'error' => $e->getMessage()]);
        }
        exit;
    }

    public function competitorWorkspace(int $id): void
    {
        $page = $this->model->getById($id);
        if (!$page) {
            Response::redirect('/admin/ai-landing-pages');
        }

        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            Response::redirect('/admin/ai-landing-pages/edit/' . $id);
        }

        $productPages = $this->model->getByProduct((int)$page['product_id']);
        $agent = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
        $history = is_array($agent['competitor_history'] ?? null) ? array_reverse($agent['competitor_history']) : [];
        $selectedId = trim((string)($_GET['entry'] ?? ''));
        $report = is_array($agent['competitor_report'] ?? null) ? $agent['competitor_report'] : [];
        if ($selectedId !== '') {
            foreach ($history as $entry) {
                if ((string)($entry['id'] ?? '') === $selectedId && is_array($entry['report'] ?? null)) {
                    $report = $entry['report'];
                    break;
                }
            }
        }

        $success = $_SESSION['lp_success'] ?? null;
        $error = $_SESSION['lp_error'] ?? null;
        if ($success) {
            unset($_SESSION['lp_success']);
        }
        if ($error) {
            unset($_SESSION['lp_error']);
        }

        extract([
            'page' => $page,
            'product' => $product,
            'productPages' => $productPages,
            'agent' => $agent,
            'history' => $history,
            'report' => $report,
            'selectedId' => $selectedId,
            'success' => $success,
            'error' => $error,
        ]);

        require ROOT_PATH . '/admin/templates/ai_landing_pages/competitor_workspace.php';
        exit;
    }

    public function productionWorkspace(int $id): void
    {
        $page = $this->model->getById($id);
        if (!$page) {
            Response::redirect('/admin/ai-landing-pages');
        }

        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            Response::redirect('/admin/ai-landing-pages/edit/' . $id);
        }

        $productPages = $this->model->getByProduct((int)$page['product_id']);
        $agent = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
        $workspace = is_array($agent['workspace'] ?? null) ? $agent['workspace'] : [];
        $briefs = is_array($agent['brief_history'] ?? null) && !empty($agent['brief_history']) ? $agent['brief_history'] : (is_array($agent['briefs'] ?? null) ? $agent['briefs'] : []);
        $tasks = is_array($workspace['tasks'] ?? null) ? $workspace['tasks'] : [];
        $destinations = is_array($agent['destinations'] ?? null) ? array_values($agent['destinations']) : [];
        $workflows = is_array($agent['destination_workflows'] ?? null) ? $agent['destination_workflows'] : [];
        $history = is_array($agent['history'] ?? null) ? array_reverse($agent['history']) : [];

        extract([
            'page' => $page,
            'product' => $product,
            'productPages' => $productPages,
            'agent' => $agent,
            'workspace' => $workspace,
            'briefs' => $briefs,
            'tasks' => $tasks,
            'destinations' => $destinations,
            'workflows' => $workflows,
            'history' => $history,
        ]);

        require ROOT_PATH . '/admin/templates/ai_landing_pages/production_workspace.php';
        exit;
    }

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

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        $payload = json_decode((string)($_POST['analysis_json'] ?? ''), true);
        if (!is_array($payload)) {
            echo json_encode(['success' => false, 'error' => 'Invalid analysis payload']);
            exit;
        }

        $agentTrace = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
        $agentTrace['analysis_form'] = array_merge(
            is_array($agentTrace['analysis_form'] ?? null) ? $agentTrace['analysis_form'] : [],
            $payload
        );
        $workspace = is_array($agentTrace['workspace'] ?? null) ? $agentTrace['workspace'] : [];
        if (!empty($payload['selected_language'])) {
            $workspace['selected_language'] = trim((string)$payload['selected_language']);
        }
        if (!empty($payload['selected_dialect'])) {
            $workspace['selected_dialect'] = trim((string)$payload['selected_dialect']);
        }
        $agentTrace['workspace'] = $workspace;
        $agentTrace['history'] = $this->appendAgentHistory(
            is_array($agentTrace['history'] ?? null) ? $agentTrace['history'] : [],
            'analysis_saved',
            'تم حفظ نموذج التحليل وتحديثه داخل الاستوديو.'
        );
        $agentTrace = $this->appendSessionSnapshot(
            $agentTrace,
            'تحديث Product Analysis',
            'تم حفظ الحقول الرئيسية للمنتج والجمهور واللغة واللهجة.',
            'analysis'
        );

        $this->model->update($id, ['agent_trace' => $agentTrace]);

        echo json_encode([
            'success' => true,
            'agent' => $agentTrace,
            'message' => 'تم حفظ تحليل المنتج.',
        ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

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

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        $payload = json_decode((string)($_POST['workspace_json'] ?? ''), true);
        if (!is_array($payload)) {
            echo json_encode(['success' => false, 'error' => __('landing.invalid_workspace_payload', 'Invalid workspace payload.')]);
            exit;
        }

        $agentTrace = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
        $workspace = is_array($agentTrace['workspace'] ?? null) ? $agentTrace['workspace'] : [];

        if (isset($payload['session_title'])) {
            $workspace['session_title'] = trim((string)$payload['session_title']);
        }
        if (isset($payload['selected_style'])) {
            $workspace['selected_style'] = trim((string)$payload['selected_style']);
        }
        if (isset($payload['selected_language'])) {
            $workspace['selected_language'] = trim((string)$payload['selected_language']);
        }
        if (isset($payload['selected_dialect'])) {
            $workspace['selected_dialect'] = trim((string)$payload['selected_dialect']);
        }
        if (isset($payload['current_objective'])) {
            $workspace['current_objective'] = trim((string)$payload['current_objective']);
        }
        if (isset($payload['selected_destinations']) && is_array($payload['selected_destinations'])) {
            $workspace['selected_destinations'] = array_values(array_unique(array_filter(array_map(static function ($item): string {
                return trim((string)$item);
            }, $payload['selected_destinations']))));
        }
        if (isset($payload['tasks']) && is_array($payload['tasks'])) {
            $workspace['tasks'] = array_values(array_map(function ($task, int $index): array {
                if (!is_array($task)) {
                    $task = [];
                }

                return [
                    'id' => trim((string)($task['id'] ?? ('task_' . ($index + 1)))),
                    'title' => trim((string)($task['title'] ?? 'Untitled task')),
                    'status' => in_array(($task['status'] ?? ''), ['todo', 'doing', 'done'], true) ? $task['status'] : 'todo',
                    'owner' => trim((string)($task['owner'] ?? 'AI Agent')),
                    'note' => trim((string)($task['note'] ?? '')),
                    'destination' => trim((string)($task['destination'] ?? '')),
                    'priority' => in_array(($task['priority'] ?? ''), ['low', 'medium', 'high'], true) ? $task['priority'] : 'medium',
                ];
            }, $payload['tasks'], array_keys($payload['tasks'])));
        }

        $agentTrace['workspace'] = $workspace;
        $agentTrace['history'] = $this->appendAgentHistory(
            is_array($agentTrace['history'] ?? null) ? $agentTrace['history'] : [],
            'workspace_saved',
            'تم حفظ حالة مساحة العمل وتفضيلات الاستوديو.'
        );
        $agentTrace = $this->appendSessionSnapshot(
            $agentTrace,
            'حفظ مساحة العمل',
            'تم حفظ الـ style الحالي، الوجهات المفعلة، والمهام المرتبطة بالجولة الحالية.',
            'workspace'
        );

        $this->model->update($id, ['agent_trace' => $agentTrace]);

        echo json_encode([
            'success' => true,
            'agent' => $agentTrace,
            'message' => __('landing.workspace_saved', 'Workspace saved successfully.'),
        ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

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

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            echo json_encode(['success' => false, 'error' => __('landing.product_missing', 'Product not found')]);
            exit;
        }

        $destination = trim((string)($_POST['destination'] ?? 'landing_page'));
        $conceptName = trim((string)($_POST['concept'] ?? ''));
        $brief = $this->buildDestinationBrief($page, $product, $destination, $conceptName);

        $agentTrace = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
        $briefHistory = is_array($agentTrace['brief_history'] ?? null) ? $agentTrace['brief_history'] : [];
        $briefHistory[] = $brief;
        $agentTrace['brief_history'] = array_slice($briefHistory, -12);
        $workspace = is_array($agentTrace['workspace'] ?? null) ? $agentTrace['workspace'] : [];
        $workspaceTasks = is_array($workspace['tasks'] ?? null) ? $workspace['tasks'] : [];
        $workspaceTasks[] = [
            'id' => 'task_' . substr(md5($brief['id'] . microtime(true)), 0, 8),
            'title' => 'تنفيذ ' . ($brief['destination_label'] ?? $destination),
            'status' => 'todo',
            'owner' => 'AI Agent',
            'note' => $brief['summary'] ?? '',
            'destination' => $brief['destination'] ?? $destination,
            'priority' => 'high',
        ];
        $workspace['tasks'] = array_slice($workspaceTasks, -18);
        $agentTrace['workspace'] = $workspace;
        $agentTrace['history'] = $this->appendAgentHistory(
            is_array($agentTrace['history'] ?? null) ? $agentTrace['history'] : [],
            'brief_generated',
            'تم توليد brief جديد للوجهة: ' . ($brief['destination_label'] ?? $destination)
        );
        $agentTrace = $this->appendSessionSnapshot(
            $agentTrace,
            'توليد Brief جديد',
            'تم إنشاء brief جديد للوجهة: ' . ($brief['destination_label'] ?? $destination),
            'brief'
        );

        $conversation = is_array($page['conversation'] ?? null) ? $page['conversation'] : [];
        $conversation[] = [
            'role' => 'assistant',
            'content' => $brief['title'] . "\n" . $brief['summary'],
        ];

        $this->model->update($id, [
            'agent_trace' => $agentTrace,
            'conversation' => $conversation,
        ]);

        echo json_encode([
            'success' => true,
            'brief' => $brief,
            'agent' => $agentTrace,
            'conversation' => $conversation,
        ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

    /* =====================================================
       AJAX — Import HTML from external URL (e.g. just.ad)
       POST /admin/ai-landing-pages/import-html/{id}
    ===================================================== */
    public function importHtml(int $id): void
    {
        header('Content-Type: application/json; charset=utf-8');

        \Core\System\Csrf::check();

        $page = $this->model->getById($id);
        if (!$page) {
            echo json_encode(['success' => false, 'error' => __('lp.page_not_found', 'Page not found')]);
            exit;
        }

        $url = trim($_POST['url'] ?? '');

        // Also accept directly pasted HTML
        $pastedHtml = trim($_POST['html'] ?? '');

        if ($pastedHtml !== '') {
            // Direct HTML paste — sanitize and store
            $html = $this->sanitizeImportedHtml($pastedHtml);
            $this->model->update($id, ['html_content' => $html]);
            echo json_encode(['success' => true, 'html' => $html]);
            exit;
        }

        if ($url === '' || !filter_var($url, FILTER_VALIDATE_URL)) {
            echo json_encode(['success' => false, 'error' => __('lp.invalid_url', 'Invalid URL.')]);
            exit;
        }

        // ── SSRF protection ──────────────────────────────────────────────────
        // Allow only http/https schemes
        $parsedUrl = parse_url($url);
        $scheme    = strtolower($parsedUrl['scheme'] ?? '');
        if (!in_array($scheme, ['http', 'https'], true)) {
            echo json_encode(['success' => false, 'error' => __('lp.invalid_url', 'Invalid URL.')]);
            exit;
        }
        $hostname = strtolower($parsedUrl['host'] ?? '');
        if ($hostname === '') {
            echo json_encode(['success' => false, 'error' => __('lp.invalid_url', 'Invalid URL.')]);
            exit;
        }
        // Resolve hostname to IP and block private/loopback/reserved ranges
        $ip = gethostbyname($hostname);
        if (
            $ip === $hostname  // DNS failed
            || !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)
        ) {
            echo json_encode(['success' => false, 'error' => __('lp.ssrf_blocked', 'Access to this URL is not allowed.')]);
            exit;
        }
        // ─────────────────────────────────────────────────────────────────────

        // Fetch HTML from URL
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => false,   // disable redirects to prevent redirect-based SSRF
            CURLOPT_TIMEOUT        => 10,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_SSL_VERIFYHOST => 2,
            CURLOPT_HTTPHEADER     => [
                'User-Agent: Mozilla/5.0 (compatible; MTEngine/1.0)',
                'Accept: text/html',
            ],
        ]);
        $fetched  = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($fetched === false || $httpCode !== 200) {
            echo json_encode(['success' => false, 'error' => 'Failed to fetch URL (HTTP ' . $httpCode . ')']);
            exit;
        }

        $html = $this->sanitizeImportedHtml($fetched);
        $this->model->update($id, ['html_content' => $html, 'conversation' => []]);

        echo json_encode(['success' => true, 'html' => $html]);
        exit;
    }

    /**
     * Sanitize imported HTML — remove dangerous scripts while keeping layout
     */
    private function sanitizeImportedHtml(string $html): string
    {
        // Remove <script> tags that could be XSS
        $html = preg_replace('/<script\b[^>]*>.*?<\/script>/is', '', $html);
        // Remove dangerous event handlers
        $html = preg_replace('/\s+on\w+\s*=\s*["\'][^"\']*["\']/i', '', $html);
        $html = preg_replace('/javascript\s*:/i', 'removed:', $html);
        return $html;
    }

    private function runImagePipeline(int $id, ?array $uploadedFile = null): array
    {
        $page = $this->model->getById($id);
        if (!$page) {
            throw new \RuntimeException(__('lp.page_not_found', 'Page not found'));
        }

        $product = $this->products->getById((int)$page['product_id']);
        if (!$product) {
            throw new \RuntimeException(__('landing.product_missing', 'Product not found'));
        }

        $sourceImage = $page['source_image'] ?? null;
        if ($uploadedFile && !empty($uploadedFile['tmp_name'])) {
            $upload = new UploadService(ROOT_PATH . '/uploads', '/uploads');
            $sourceImage = $upload->storeImage($uploadedFile, 'landing-pages/source-images');
        }

        if (!$sourceImage) {
            throw new \RuntimeException(__('landing.source_image_required', 'Please upload a screenshot or landing page design first.'));
        }

        $diskPath = ROOT_PATH . '/' . ltrim($sourceImage, '/');
        if (!is_file($diskPath)) {
            throw new \RuntimeException(__('landing.source_image_missing', 'The uploaded source image could not be found on disk.'));
        }

        $analysisService = new LandingImageAnalysisService();
        $analysis = $analysisService->analyze($product, $diskPath);

        $structureBuilder = new LandingStructureBuilder();
        $structure = $structureBuilder->build($analysis, $product);

        $landingService = new AiLandingPageService();
        try {
            $html = $landingService->generateFromStructure($product, $structure, [
                'existing_html' => $page['html_content'] ?? null,
            ]);
        } catch (\Throwable $e) {
            $html = $this->buildEmergencyLandingHtml($product, $analysis, $structure);
        }

        $html = $this->sanitizeImportedHtml($html);
        $agentResult = $this->buildStudioSnapshot($product, $analysis, $structure, $html);
        $agentResult = $this->appendSessionSnapshot(
            $agentResult,
            'بناء الـ Workspace من الصورة',
            'تم تحليل الصورة المرجعية وتوليد أول workspace كامل منها.',
            'analysis'
        );

        $conversation = $page['conversation'] ?? [];
        $conversation[] = [
            'role' => 'assistant',
            'content' => __('landing.image_pipeline_note', 'The AI agent analyzed the uploaded image, planned the layout, generated the page, and improved it automatically.'),
        ];

        $this->model->update($id, [
            'source_mode' => 'image',
            'source_image' => $sourceImage,
            'analysis_json' => $analysis,
            'structure_json' => $structure,
            'agent_trace' => $agentResult,
            'html_content' => $html,
            'conversation' => $conversation,
        ]);

        return [
            'html' => $html,
            'analysis' => $analysis,
            'structure' => $structure,
            'agent' => $agentResult,
            'agent_trace' => $agentResult,
            'source_image' => $this->absoluteAssetUrl($sourceImage),
        ];
    }

    private function buildStudioSnapshot(array $product, array $analysis, array $structure, string $html): array
    {
        $productName = (string)($product['title'] ?? $product['name'] ?? __('landing.product', 'Product'));
        $hero = is_array($analysis['hero'] ?? null) ? $analysis['hero'] : [];
        $visual = is_array($structure['visual_system'] ?? null)
            ? $structure['visual_system']
            : (is_array($analysis['visual_system'] ?? null) ? $analysis['visual_system'] : []);
        $sections = is_array($structure['sections'] ?? null) ? $structure['sections'] : [];
        $quickWins = is_array($analysis['conversion_notes'] ?? null) ? $analysis['conversion_notes'] : [];
        $palette = array_values(array_filter([
            $visual['primary_color'] ?? null,
            $visual['secondary_color'] ?? null,
            $visual['accent_color'] ?? null,
            $analysis['dominant_color'] ?? null,
        ]));
        $productType = $this->stringifyValue($analysis['product_type'] ?? $analysis['type'] ?? '');
        $brandName = $this->stringifyValue($analysis['brand'] ?? $analysis['brand_name'] ?? '');
        $category = $this->stringifyValue($analysis['category'] ?? $product['category_name'] ?? '');
        $audience = $this->stringifyValue($analysis['target_audience'] ?? 'جمهور يبحث عن حل واضح وسريع');
        $problem = $this->stringifyValue($analysis['problem'] ?? $analysis['pain_point'] ?? 'مشكلة متكررة تحتاج حلاً سريعًا وواضحًا.');
        $languageOptions = [
            ['code' => 'fr', 'label' => 'Français'],
            ['code' => 'en', 'label' => 'English'],
            ['code' => 'ar', 'label' => 'العربية'],
            ['code' => 'ar-dz', 'label' => 'الدارجة الجزائرية'],
        ];
        $stylePresets = [
            [
                'id' => 'luxe_nocturne',
                'name' => 'Luxe Nocturne',
                'summary' => 'ستايل فاخر بتباين قوي، مناسب للمنتجات premium والـ hero البصري.',
                'chips' => ['Premium', 'Dark Contrast', 'Luxury'],
                'mood' => 'سينمائي، فاخر، contrast مرتفع',
                'direction' => 'Hero بصري كبير مع callouts قليلة وراقية',
                'active' => true,
            ],
            [
                'id' => 'lifestyle_driver',
                'name' => 'Lifestyle Driver',
                'summary' => 'يعتمد على مشاهد استعمال المنتج داخل الحياة اليومية مع CTA مباشر.',
                'chips' => ['Lifestyle', 'Human Proof', 'Warm Light'],
                'mood' => 'دافئ، عملي، اجتماعي',
                'direction' => 'صور استعمال + social proof + CTA سريع',
                'active' => false,
            ],
            [
                'id' => 'minimal_conversion',
                'name' => 'Minimal Conversion',
                'summary' => 'واجهة نظيفة تركّز على العرض، الفوائد، وصندوق الطلب بدون تشتيت.',
                'chips' => ['Minimal', 'Fast CTA', 'COD'],
                'mood' => 'تحويلي مباشر، سريع، واضح',
                'direction' => 'Content قصير، proof blocks، order box مبكر',
                'active' => false,
            ],
        ];

        $concepts = [
            [
                'name' => 'زاوية النتيجة',
                'angle' => 'ابدأ بالفائدة النهائية التي سيشعر بها العميل مباشرة.',
                'hook' => (string)($hero['headline'] ?? ('نتيجة واضحة مع ' . $productName)),
            ],
            [
                'name' => 'زاوية المشكلة',
                'angle' => 'ابدأ بالمشكلة ثم قدّم المنتج كحل مباشر وسريع.',
                'hook' => 'حل عملي لمشكلة متكررة قبل أن تتفاقم.',
            ],
            [
                'name' => 'زاوية الثقة',
                'angle' => 'اعرض عناصر الطمأنة والضمان والطلب عند الاستلام.',
                'hook' => 'منتج موثوق مع تجربة شراء أوضح وثقة أعلى.',
            ],
        ];

        $destinations = [
            'landing_page' => [
                'id' => 'landing_page',
                'title' => 'Brief LP',
                'goal' => 'تحويل الصورة المرجعية إلى Landing Page قابلة للنشر.',
                'notes' => array_slice($quickWins, 0, 3),
                'icon' => 'bi-window-stack',
                'status' => 'ready',
                'deliverables' => ['Hero', 'Sections', 'Order Box', 'Preview'],
            ],
            'static_ads' => [
                'id' => 'static_ads',
                'title' => 'Brief Static Ads',
                'goal' => 'توليد زوايا إعلانية ثابتة متوافقة مع نفس المرجع.',
                'notes' => ['Hook', 'Offer', 'Visual angle'],
                'icon' => 'bi-image',
                'status' => 'ready',
                'deliverables' => ['Concepts', 'Hooks', 'Art direction'],
            ],
            'video_brief' => [
                'id' => 'video_brief',
                'title' => 'Brief Video',
                'goal' => 'اشتقاق brief لفيديو قصير من نفس التحليل.',
                'notes' => ['Storyboard', 'Voiceover', 'Scene hooks'],
                'icon' => 'bi-camera-reels',
                'status' => 'ready',
                'deliverables' => ['Scenes', 'Voiceover', 'CTA ending'],
            ],
            'ad_copies' => [
                'id' => 'ad_copies',
                'title' => 'Ad Copies',
                'goal' => 'كتابة نصوص إعلانية متعددة من نفس المنتج والزوايا.',
                'notes' => ['Primary text', 'Headline', 'CTA'],
                'icon' => 'bi-pencil-square',
                'status' => 'ready',
                'deliverables' => ['Primary text', 'Headline', 'CTA'],
            ],
            'nextify' => [
                'id' => 'nextify',
                'title' => 'Brief Nextify',
                'goal' => 'اشتقاق brief جاهز لإنتاج visual prompt/creative system شبيه بمنصات creative automation.',
                'notes' => ['Creative prompt', 'Layout constraints', 'Mood board'],
                'icon' => 'bi-magic',
                'status' => 'ready',
                'deliverables' => ['Master prompt', 'Visual specs', 'Copy blocks'],
            ],
        ];

        $briefs = [
            [
                'id' => 'brief_lp_seed',
                'destination' => 'landing_page',
                'destination_label' => 'Landing Page',
                'type' => 'brief_lp',
                'title' => 'Landing Page Brief',
                'objective' => 'صفحة تحويل مهيأة لسوق COD الجزائري مع CTA واضح وثقة عالية.',
                'prompt' => 'ابن صفحة تحويل تبدأ بهيرو قوي، فوائد واضحة، Social Proof، FAQ، وصندوق طلب مباشر.',
                'status' => 'ready',
                'summary' => 'هيكل الصفحة النهائي: Hero قوي، proof سريع، FAQs، وصندوق طلب.',
                'deliverables' => ['Hero', 'Benefits', 'FAQ', 'Checkout'],
            ],
            [
                'id' => 'brief_static_seed',
                'destination' => 'static_ads',
                'destination_label' => 'Static Ads',
                'type' => 'brief_static_ads',
                'title' => 'Static Ads Brief',
                'objective' => 'توليد 3 إلى 5 زوايا إعلانية ثابتة من نفس المنتج.',
                'prompt' => 'ولّد visual concepts مختلفة: ألم، نتيجة، ثقة، مقارنة، وعرض.',
                'status' => 'ready',
                'summary' => 'سنستخرج angles جاهزة لحملات static ads من نفس التحليل.',
                'deliverables' => ['Angles', 'Hooks', 'Visual styles'],
            ],
            [
                'id' => 'brief_video_seed',
                'destination' => 'video_brief',
                'destination_label' => 'Video Brief',
                'type' => 'brief_video',
                'title' => 'Video Brief',
                'objective' => 'تقسيم الزاوية إلى hook + body + CTA لفيديو قصير.',
                'prompt' => 'حوّل أفضل concept إلى storyboard مختصر مع transitions وvoiceover.',
                'status' => 'ready',
                'summary' => 'Storyboard قصير من نفس الرسالة التسويقية مع CTA نهائي.',
                'deliverables' => ['Hook', 'Storyboard', 'Voiceover'],
            ],
            [
                'id' => 'brief_nextify_seed',
                'destination' => 'nextify',
                'destination_label' => 'Nextify',
                'type' => 'brief_nextify',
                'title' => 'Brief Nextify',
                'objective' => 'تجهيز creative prompt system منظم لنفس المنتج والزوايا البصرية.',
                'prompt' => 'حوّل تحليل المنتج والصورة المرجعية إلى master prompt إبداعي مع palette وlayout rules ونصوص رئيسية.',
                'status' => 'ready',
                'summary' => 'Creative system منظم يمكن تصديره أو استخدامه داخل أي pipeline بصري لاحقًا.',
                'deliverables' => ['Master prompt', 'Layout rules', 'Palette', 'Text zones'],
            ],
        ];

        $enrichedSections = array_map(function (array $section, int $index) use ($palette): array {
            $type = $this->stringifyValue($section['type'] ?? 'section');
            $headline = $this->stringifyValue($section['headline'] ?? $section['label'] ?? '');
            $purpose = $this->stringifyValue($section['purpose'] ?? $section['subheadline'] ?? '');

            return array_merge($section, [
                'id' => 'section_' . ($index + 1),
                'type' => $type,
                'headline' => $headline,
                'purpose' => $purpose,
                'hook' => $headline !== '' ? $headline : ('قسم ' . ($index + 1)),
                'objective' => $purpose !== '' ? $purpose : 'دعم التحويل داخل الصفحة',
                'layout' => $this->inferSectionLayout($type),
                'difficulty' => $this->inferSectionDifficulty($type),
                'copy_prompt' => 'اكتب هذا القسم بحيث يخدم الهدف: ' . ($purpose !== '' ? $purpose : $headline),
                'palette' => array_slice($palette, 0, 3),
                'layout_notes' => 'استخدم Layout من نوع ' . $this->inferSectionLayout($type) . ' مع spacing مريح وموبايل أولاً.',
                'text_rules' => [
                    'اختصر العنوان وابدأ بالفعل أو النتيجة.',
                    'حافظ على CTA واضح يخاطب العميل الجزائري.',
                    'أظهر benefit أو proof قبل الانتقال للقسم التالي.',
                ],
            ]);
        }, $sections, array_keys($sections));

        $baseScore = min(96, 68 + (count($sections) * 4));
        $scoreBreakdown = [
            'global' => $baseScore,
            'copy' => min(95, $baseScore - 4),
            'design' => !empty($visual) ? 84 : 72,
            'cta' => 80 + min(12, count($concepts) * 3),
            'trust' => 78 + (in_array('faq', array_column($enrichedSections, 'type'), true) ? 8 : 0),
            'mobile' => 81,
            'cod_fit' => 88,
        ];

        return [
            'product_card' => [
                'product_name' => $productName,
                'brand' => $brandName,
                'category' => $category,
                'product_type' => $productType,
                'audience' => $audience,
                'problem' => $problem,
                'primary_cta' => $this->stringifyValue($hero['cta'] ?? 'اطلب الآن'),
                'palette' => $palette,
                'language' => 'ar-dz',
                'market' => 'DZ COD',
            ],
            'analysis_form' => [
                'product_name' => $productName,
                'brand' => $brandName,
                'category' => $category,
                'product_type' => $productType,
                'primary_benefit' => $this->stringifyValue($analysis['main_benefit'] ?? $hero['headline'] ?? ''),
                'audience' => $audience,
                'pain_point' => $problem,
                'palette' => $palette,
                'language_options' => $languageOptions,
                'selected_language' => 'ar-dz',
                'market' => 'Algerian COD',
            ],
            'styles' => $stylePresets,
            'destinations' => $destinations,
            'briefs' => $briefs,
            'brief_history' => [],
            'workspace' => [
                'session_title' => 'جلسة ' . $productName,
                'selected_style' => 'luxe_nocturne',
                'selected_language' => 'ar',
                'selected_dialect' => 'ar-dz',
                'current_objective' => 'بناء صفحة تحويل قوية قابلة للنشر ثم اشتقاق outputs أخرى من نفس التحليل.',
                'selected_destinations' => ['landing_page', 'static_ads', 'video_brief', 'ad_copies', 'nextify'],
                'tasks' => [
                    [
                        'id' => 'task_seed_1',
                        'title' => 'مراجعة Product Analysis Form',
                        'status' => 'doing',
                        'owner' => 'AI Agent',
                        'note' => 'تأكد من الاسم، الجمهور، والـ pain point قبل التوليد.',
                        'destination' => 'landing_page',
                        'priority' => 'high',
                    ],
                    [
                        'id' => 'task_seed_2',
                        'title' => 'اختيار الـ Style الأنسب',
                        'status' => 'todo',
                        'owner' => 'You',
                        'note' => 'اختر بين luxe, lifestyle, أو minimal conversion.',
                        'destination' => 'static_ads',
                        'priority' => 'medium',
                    ],
                    [
                        'id' => 'task_seed_3',
                        'title' => 'تجميع أقوى concept داخل الصفحة',
                        'status' => 'todo',
                        'owner' => 'AI Agent',
                        'note' => 'استخدم section planner ثم assemble.',
                        'destination' => 'landing_page',
                        'priority' => 'high',
                    ],
                ],
                'session_history' => [
                    [
                        'id' => 'session_seed_' . substr(md5($productName), 0, 8),
                        'title' => 'تهيئة أولية لـ ' . $productName,
                        'summary' => 'اكتمل تحليل الصورة وتجهيز أول snapshot من مساحة العمل.',
                        'stage' => 'analysis',
                        'at' => gmdate('c'),
                        'metrics' => [
                            'sections' => count($enrichedSections),
                            'concepts' => count($concepts),
                            'briefs' => count($briefs),
                            'variants' => 0,
                        ],
                    ],
                ],
            ],
            'competitor_history' => [],
            'history' => [
                [
                    'type' => 'pipeline_ready',
                    'label' => 'اكتمل تحليل الصورة وبناء الـ workspace.',
                    'at' => gmdate('c'),
                ],
            ],
            'concepts' => $concepts,
            'selected_concept' => $concepts[0]['name'],
            'section_blueprint' => [
                'selected_concept' => $concepts[0]['name'],
                'sections' => $enrichedSections,
            ],
            'sections' => $enrichedSections,
            'scorecard' => [
                'conversion_score' => $scoreBreakdown['global'],
                'global_score' => $scoreBreakdown['global'],
                'quick_wins' => array_slice($quickWins, 0, 4),
                'visual_score' => $scoreBreakdown['design'],
                'breakdown' => $scoreBreakdown,
            ],
            'final_evaluation' => [
                'score' => $scoreBreakdown['global'],
                'issues' => [],
            ],
            'html' => $html,
        ];
    }

    private function appendAgentHistory(array $history, string $type, string $label, array $meta = []): array
    {
        $history[] = [
            'id' => 'event_' . substr(md5($type . $label . microtime(true)), 0, 10),
            'type' => $type,
            'label' => $label,
            'meta' => $meta,
            'at' => gmdate('c'),
        ];

        return array_slice($history, -40);
    }

    private function buildDestinationBrief(array $page, array $product, string $destination, string $conceptName = ''): array
    {
        $agentTrace = is_array($page['agent_trace'] ?? null) ? $page['agent_trace'] : [];
        $analysisForm = is_array($agentTrace['analysis_form'] ?? null) ? $agentTrace['analysis_form'] : [];
        $concepts = is_array($agentTrace['concepts'] ?? null) ? $agentTrace['concepts'] : [];
        $selectedConcept = $conceptName !== ''
            ? $conceptName
            : (string)($agentTrace['selected_concept'] ?? ($concepts[0]['name'] ?? 'زاوية النتيجة'));
        $productName = trim((string)($analysisForm['product_name'] ?? $product['title'] ?? $product['name'] ?? 'المنتج'));
        $audience = trim((string)($analysisForm['audience'] ?? 'سوق يبحث عن حل سريع وواضح'));
        $painPoint = trim((string)($analysisForm['pain_point'] ?? 'مشكلة تحتاج حلًا مباشرًا'));
        $primaryBenefit = trim((string)($analysisForm['primary_benefit'] ?? 'نتيجة واضحة ومقنعة'));

        $config = [
            'landing_page' => [
                'label' => 'Landing Page',
                'title' => 'Brief LP — ' . $productName,
                'summary' => 'أنشئ صفحة هبوط تحويلية لسوق COD الجزائري تبدأ بهيرو قوي، proof سريع، FAQ، وصندوق طلب واضح.',
                'objective' => 'رفع التحويل عبر Hero واضح، Offer مباشر، وثقة عالية.',
                'deliverables' => ['Hero', 'Benefits', 'Proof', 'FAQ', 'Order Box'],
            ],
            'static_ads' => [
                'label' => 'Static Ads',
                'title' => 'Brief Static Ads — ' . $productName,
                'summary' => 'ولّد مجموعة زوايا static ads من نفس التحليل مع hooks مختلفة لكل creative.',
                'objective' => 'استخراج concepts وحملات visual hooks جاهزة للإعلان.',
                'deliverables' => ['3-5 Concepts', 'Hooks', 'Visual directions'],
            ],
            'video_brief' => [
                'label' => 'Video Brief',
                'title' => 'Brief Video — ' . $productName,
                'summary' => 'حوّل أفضل concept إلى storyboard قصير مناسب لفيديو performance.',
                'objective' => 'بناء Hook + Body + CTA لفيديو قصير يشرح الفائدة بسرعة.',
                'deliverables' => ['Storyboard', 'Voiceover', 'CTA ending'],
            ],
            'ad_copies' => [
                'label' => 'Ad Copies',
                'title' => 'Ad Copies — ' . $productName,
                'summary' => 'اكتب نسخًا إعلانية متعددة باللغة واللهجة المناسبة لنفس المنتج.',
                'objective' => 'رفع جودة النصوص الإعلانية عبر hooks وCTA أقوى.',
                'deliverables' => ['Primary text', 'Headline', 'CTA'],
            ],
            'nextify' => [
                'label' => 'Nextify',
                'title' => 'Brief Nextify — ' . $productName,
                'summary' => 'ابن Creative Prompt System بصري منظم لنفس المنتج يمكن استخدامه في outputs بصرية لاحقة.',
                'objective' => 'تحويل التحليل الحالي إلى نظام prompt + layout + palette + copy zones.',
                'deliverables' => ['Master prompt', 'Layout rules', 'Palette', 'Copy blocks'],
            ],
        ];

        $chosen = $config[$destination] ?? $config['landing_page'];

        return [
            'id' => 'brief_' . substr(md5($destination . $productName . microtime(true)), 0, 10),
            'destination' => $destination,
            'destination_label' => $chosen['label'],
            'title' => $chosen['title'],
            'summary' => $chosen['summary'],
            'objective' => $chosen['objective'],
            'concept' => $selectedConcept,
            'prompt' => 'المنتج: ' . $productName . "\n"
                . 'الجمهور: ' . $audience . "\n"
                . 'المشكلة: ' . $painPoint . "\n"
                . 'الفائدة الأساسية: ' . $primaryBenefit . "\n"
                . 'الزاوية المختارة: ' . $selectedConcept,
            'deliverables' => $chosen['deliverables'],
            'status' => 'ready',
            'created_at' => gmdate('c'),
        ];
    }

    private function normalizeDestination(string $destination): string
    {
        $allowed = ['landing_page', 'static_ads', 'video_brief', 'ad_copies', 'nextify'];
        return in_array($destination, $allowed, true) ? $destination : 'landing_page';
    }

    private function ensureDestinationWorkflows(array $agentTrace, array $page, array $product): array
    {
        $workflows = is_array($agentTrace['destination_workflows'] ?? null) ? $agentTrace['destination_workflows'] : [];
        foreach (['landing_page', 'static_ads', 'video_brief', 'ad_copies', 'nextify'] as $destination) {
            if (!isset($workflows[$destination]) || !is_array($workflows[$destination])) {
                $workflows[$destination] = $this->buildDestinationWorkflowSeed($destination, $page, $product, $agentTrace);
            }
        }
        $agentTrace['destination_workflows'] = $workflows;
        return $agentTrace;
    }

    private function buildDestinationWorkflowSeed(string $destination, array $page, array $product, array $agentTrace): array
    {
        $brief = $this->buildDestinationBrief($page, $product, $destination, (string)($agentTrace['selected_concept'] ?? ''));
        $configs = [
            'landing_page' => [
                'title' => 'Landing Page Workflow',
                'goal' => 'تحويل التحليل الحالي إلى صفحة هبوط كاملة قابلة للنشر.',
                'deliverables' => ['Final LP brief', 'Section roadmap', 'Publish-ready guidance'],
            ],
            'static_ads' => [
                'title' => 'Static Ads Workflow',
                'goal' => 'إنتاج زوايا static ads قابلة للتنفيذ من نفس المرجع.',
                'deliverables' => ['Ad concepts', 'Hooks', 'Visual directions'],
            ],
            'video_brief' => [
                'title' => 'Video Brief Workflow',
                'goal' => 'تحويل أقوى concept إلى storyboard وvoiceover تنفيذي.',
                'deliverables' => ['Storyboard', 'Shot list', 'Voiceover'],
            ],
            'ad_copies' => [
                'title' => 'Ad Copies Workflow',
                'goal' => 'إنتاج نسخ إعلانية متعددة باللهجة والسوق المناسبين.',
                'deliverables' => ['Primary texts', 'Headlines', 'CTA matrix'],
            ],
            'nextify' => [
                'title' => 'Nextify Workflow',
                'goal' => 'بناء Creative Prompt System منظم لإنتاج بصري لاحق.',
                'deliverables' => ['Master prompt', 'Layout system', 'Copy zones'],
            ],
        ];
        $config = $configs[$destination];

        return [
            'id' => 'destination_' . $destination,
            'destination' => $destination,
            'title' => $config['title'],
            'goal' => $config['goal'],
            'status' => 'ready',
            'current_stage' => 'brief',
            'deliverables' => $config['deliverables'],
            'brief' => $brief,
            'artifact' => [],
            'run_count' => 0,
            'updated_at' => gmdate('c'),
            'stages' => [
                ['id' => 'analysis', 'title' => __('landing.workflow_stage_analysis', 'التحليل'), 'status' => 'done'],
                ['id' => 'brief', 'title' => __('landing.workflow_stage_brief', 'الـ Brief'), 'status' => 'done'],
                ['id' => 'production', 'title' => __('landing.workflow_stage_production', 'الإنتاج'), 'status' => 'todo'],
                ['id' => 'review', 'title' => __('landing.workflow_stage_review', 'المراجعة'), 'status' => 'todo'],
            ],
            'history' => [[
                'id' => 'history_seed_' . substr(md5($destination), 0, 8),
                'title' => __('landing.workflow_ready_title', 'الـ Workflow جاهز'),
                'summary' => __('landing.workflow_ready_text', 'تم تجهيز هذه الوجهة لتتحول من brief إلى workflow مستقل قابل للتشغيل.'),
                'at' => gmdate('c'),
                'stage' => 'brief',
            ]],
        ];
    }

    private function buildDestinationArtifact(string $destination, array $page, array $product, array $agentTrace, array $workflow): array
    {
        $analysisForm = is_array($agentTrace['analysis_form'] ?? null) ? $agentTrace['analysis_form'] : [];
        $concepts = is_array($agentTrace['concepts'] ?? null) ? $agentTrace['concepts'] : [];
        $selectedConcept = (string)($agentTrace['selected_concept'] ?? ($concepts[0]['name'] ?? 'زاوية النتيجة'));
        $productName = trim((string)($analysisForm['product_name'] ?? $product['title'] ?? $product['name'] ?? 'المنتج'));
        $audience = trim((string)($analysisForm['audience'] ?? 'جمهور يبحث عن حل واضح وسريع'));
        $painPoint = trim((string)($analysisForm['pain_point'] ?? 'مشكلة تحتاج حلًا مباشرًا'));
        $primaryBenefit = trim((string)($analysisForm['primary_benefit'] ?? 'نتيجة واضحة ومقنعة'));
        $palette = is_array($analysisForm['palette'] ?? null) ? $analysisForm['palette'] : [];
        $paletteText = !empty($palette) ? implode(' • ', $palette) : '—';
        $brief = is_array($workflow['brief'] ?? null) ? $workflow['brief'] : $this->buildDestinationBrief($page, $product, $destination, $selectedConcept);

        switch ($destination) {
            case 'static_ads':
                return [
                    'summary' => 'تم تجهيز حزمة static ads كاملة انطلاقًا من نفس التحليل.',
                    'primary_output' => [
                        'title' => 'Creative Angles',
                        'items' => [
                            'Angle 1: ' . $selectedConcept . ' — Hook يركز على المشكلة الأساسية.',
                            'Angle 2: نتيجة مباشرة حول ' . $primaryBenefit,
                            'Angle 3: ثقة / ضمان / طلب عند الاستلام لسوق الجزائر',
                        ],
                    ],
                    'secondary_output' => [
                        'title' => 'Visual Direction',
                        'items' => [
                            'Audience: ' . $audience,
                            'Palette: ' . $paletteText,
                            'Pain Point: ' . $painPoint,
                        ],
                    ],
                    'checklist' => ['اختيار أفضل Angle', 'ربط hook بصورة المنتج', 'إنتاج 3 تصاميم ثابتة', 'اختبار CTA'],
                ];
            case 'video_brief':
                return [
                    'summary' => 'تم بناء Video Brief تنفيذي من نفس الزاوية المختارة.',
                    'primary_output' => [
                        'title' => 'Storyboard',
                        'items' => [
                            'Scene 1: عرض المشكلة — ' . $painPoint,
                            'Scene 2: المنتج كحل سريع — ' . $productName,
                            'Scene 3: النتيجة النهائية — ' . $primaryBenefit,
                            'Scene 4: CTA ختامي مناسب لسوق COD الجزائري',
                        ],
                    ],
                    'secondary_output' => [
                        'title' => 'Voiceover Direction',
                        'items' => [
                            'Hook قصير ومباشر باللهجة المختارة',
                            'تركيز على الفائدة قبل التفاصيل',
                            'إغلاق بثقة + CTA',
                        ],
                    ],
                    'checklist' => ['اعتماد الـ hook', 'تحديد مدة الفيديو', 'كتابة voiceover', 'ترتيب اللقطات'],
                ];
            case 'ad_copies':
                return [
                    'summary' => 'تم تجهيز نسخ إعلانية متعددة قابلة للاختبار فورًا.',
                    'primary_output' => [
                        'title' => 'Primary Texts',
                        'items' => [
                            $productName . ' حل واضح لـ ' . $painPoint,
                            'لو راك تبحث عن ' . $primaryBenefit . ' فهذا العرض مخصص لك',
                            'حل عملي، CTA مباشر، وطلب عند الاستلام',
                        ],
                    ],
                    'secondary_output' => [
                        'title' => 'Headlines & CTA',
                        'items' => [
                            'Headline 1: ' . $productName,
                            'Headline 2: نتيجة أسرع وثقة أعلى',
                            'CTA: اطلب الآن / احجز نسختك / جرّبه اليوم',
                        ],
                    ],
                    'checklist' => ['اختيار 3 نسخ', 'اختبار headline', 'اختبار CTA', 'مراجعة اللهجة'],
                ];
            case 'nextify':
                return [
                    'summary' => 'تم إعداد Creative Prompt System منظم لهذه الوجهة.',
                    'primary_output' => [
                        'title' => 'Master Prompt System',
                        'items' => [
                            'Product: ' . $productName,
                            'Selected Concept: ' . $selectedConcept,
                            'Audience: ' . $audience,
                            'Palette: ' . $paletteText,
                        ],
                    ],
                    'secondary_output' => [
                        'title' => 'Layout Rules',
                        'items' => [
                            'Use bold hero with clear problem/solution framing',
                            'Respect CTA hierarchy and COD trust blocks',
                            'Keep visual rhythm simple and conversion-first',
                        ],
                    ],
                    'checklist' => ['اعتماد palette', 'ضبط text zones', 'تجهيز prompt النهائي', 'اختبار المخرجات البصرية'],
                ];
            case 'landing_page':
            default:
                return [
                    'summary' => 'تم تجهيز Landing Page workflow قابل للتنفيذ من brief إلى نشر.',
                    'primary_output' => [
                        'title' => 'Execution Roadmap',
                        'items' => [
                            'Hero واضح لـ ' . $productName,
                            'Benefits مرتبطة مباشرة بـ ' . $primaryBenefit,
                            'Trust + FAQ + COD CTA',
                            'Order box واضح وموجه للتحويل',
                        ],
                    ],
                    'secondary_output' => [
                        'title' => 'Commercial Direction',
                        'items' => [
                            'Audience: ' . $audience,
                            'Pain Point: ' . $painPoint,
                            'Concept: ' . $selectedConcept,
                        ],
                    ],
                    'checklist' => ['مراجعة الهيكل', 'ضبط CTA', 'فحص FAQ', 'اعتماد النسخة النهائية'],
                ];
        }
    }

    private function expandCompetitorReport(array $report, array $page, array $product, array $agentTrace, string $url): array
    {
        $scorecard = is_array($agentTrace['scorecard'] ?? null) ? $agentTrace['scorecard'] : [];
        $breakdown = is_array($scorecard['breakdown'] ?? null) ? $scorecard['breakdown'] : [];
        $sections = is_array($agentTrace['sections'] ?? null) ? $agentTrace['sections'] : [];
        $concepts = is_array($agentTrace['concepts'] ?? null) ? $agentTrace['concepts'] : [];
        $analysisForm = is_array($agentTrace['analysis_form'] ?? null) ? $agentTrace['analysis_form'] : [];

        $ourScores = [
            'global' => (int)($scorecard['global_score'] ?? $breakdown['global'] ?? 0),
            'copy' => (int)($breakdown['copy'] ?? 0),
            'design' => (int)($breakdown['design'] ?? 0),
            'cta' => (int)($breakdown['cta'] ?? 0),
            'trust' => (int)($breakdown['trust'] ?? 0),
            'mobile' => (int)($breakdown['mobile'] ?? 0),
            'cod_fit' => (int)($breakdown['cod_fit'] ?? 0),
        ];

        $competitorScores = [
            'global' => (int)($report['global_score'] ?? 0),
            'copy' => (int)($report['copy_score'] ?? max(0, ($report['global_score'] ?? 0) - 4)),
            'design' => (int)($report['design_score'] ?? max(0, ($report['global_score'] ?? 0) - 2)),
            'cta' => (int)($report['cta_score'] ?? max(0, ($report['global_score'] ?? 0) - 3)),
            'trust' => (int)($report['trust_score'] ?? max(0, ($report['global_score'] ?? 0) - 5)),
            'mobile' => (int)($report['mobile_score'] ?? max(0, ($report['global_score'] ?? 0) - 2)),
        ];

        $comparison = [
            'global_delta' => $ourScores['global'] - $competitorScores['global'],
            'copy_delta' => $ourScores['copy'] - $competitorScores['copy'],
            'design_delta' => $ourScores['design'] - $competitorScores['design'],
            'cta_delta' => $ourScores['cta'] - $competitorScores['cta'],
            'trust_delta' => $ourScores['trust'] - $competitorScores['trust'],
            'mobile_delta' => $ourScores['mobile'] - $competitorScores['mobile'],
        ];

        $priorityActions = [];
        if (($comparison['cta_delta'] ?? 0) < 0) {
            $priorityActions[] = __('landing.competitor_priority_cta', 'نحتاج CTA أوضح وأكثر حدة من المنافس.');
        }
        if (($comparison['trust_delta'] ?? 0) < 0) {
            $priorityActions[] = __('landing.competitor_priority_trust', 'يجب تقوية عناصر الثقة والضمان والـ COD داخل صفحتنا.');
        }
        if (($comparison['copy_delta'] ?? 0) < 0) {
            $priorityActions[] = __('landing.competitor_priority_copy', 'النسخ الحالية تحتاج angle أقوى ورسائل أكثر مباشرة.');
        }
        if (($comparison['global_delta'] ?? 0) >= 0) {
            $priorityActions[] = __('landing.competitor_priority_lead', 'لدينا فرصة واضحة للتفوق إذا ثبتنا الـ hook والـ offer الحاليين.');
        }

        $report['url'] = (string)($report['url'] ?? $url);
        $report['executive_summary'] = (string)($report['executive_summary'] ?? __('landing.competitor_summary_fallback', 'تم تحليل المنافس وتجهيز مقارنة تنفيذية مع صفحتنا الحالية.'));
        $report['our_scorecard'] = $ourScores;
        $report['competitor_scorecard'] = $competitorScores;
        $report['comparison'] = $comparison;
        $report['priority_actions'] = array_values(array_unique(array_merge(
            is_array($report['quick_wins'] ?? null) ? $report['quick_wins'] : [],
            $priorityActions
        )));
        $report['executive_metrics'] = [
            'our_sections' => count($sections),
            'concepts_ready' => count($concepts),
            'market' => (string)($analysisForm['market'] ?? ''),
            'audience' => (string)($analysisForm['audience'] ?? ''),
            'product' => (string)($analysisForm['product_name'] ?? $product['title'] ?? $product['name'] ?? ''),
        ];
        $report['comparison_summary'] = [
            'winner' => ($comparison['global_delta'] ?? 0) >= 0 ? 'ours' : 'competitor',
            'headline' => ($comparison['global_delta'] ?? 0) >= 0
                ? __('landing.competitor_lead_headline', 'صفحتنا حاليًا تتقدم، لكن ما زال هناك مجال لزيادة الفارق.')
                : __('landing.competitor_gap_headline', 'المنافس يتقدم في بعض المحاور، ولدينا فرصة واضحة لسد الفجوة.'),
        ];

        foreach (['strengths', 'weaknesses', 'gaps_we_can_exploit', 'recommended_sections', 'recommended_angles', 'hooks_to_try', 'cta_opportunities', 'trust_opportunities', 'ux_observations', 'offer_observations', 'quick_wins', 'priority_actions'] as $field) {
            $report[$field] = array_values(array_filter(array_map('strval', is_array($report[$field] ?? null) ? $report[$field] : [])));
        }

        return $report;
    }

    private function appendSessionSnapshot(array $agentTrace, string $title, string $summary, string $stage = 'workspace'): array
    {
        $workspace = is_array($agentTrace['workspace'] ?? null) ? $agentTrace['workspace'] : [];
        $history = is_array($workspace['session_history'] ?? null) ? $workspace['session_history'] : [];
        $sections = is_array($agentTrace['sections'] ?? null) ? $agentTrace['sections'] : [];
        $concepts = is_array($agentTrace['concepts'] ?? null) ? $agentTrace['concepts'] : [];
        $briefs = is_array($agentTrace['brief_history'] ?? null) ? $agentTrace['brief_history'] : [];
        $variants = is_array($agentTrace['variants'] ?? null) ? $agentTrace['variants'] : [];

        $history[] = [
            'id' => 'session_' . substr(md5($title . $summary . microtime(true)), 0, 10),
            'title' => $title,
            'summary' => $summary,
            'stage' => $stage,
            'at' => gmdate('c'),
            'metrics' => [
                'sections' => count($sections),
                'concepts' => count($concepts),
                'briefs' => count($briefs),
                'variants' => count($variants),
            ],
        ];

        $workspace['session_history'] = array_slice($history, -12);
        $agentTrace['workspace'] = $workspace;

        return $agentTrace;
    }

    private function inferSectionLayout(string $type): string
    {
        switch ($type) {
            case 'hero':
                return 'hero_split';
            case 'benefits':
                return '3_cards';
            case 'social-proof':
            case 'testimonials':
                return 'proof_stack';
            case 'comparison':
                return 'comparison_grid';
            case 'faq':
                return 'accordion';
            case 'checkout':
            case 'cta':
                return 'checkout_focus';
            default:
                return 'stacked';
        }
    }

    private function inferSectionDifficulty(string $type): string
    {
        switch ($type) {
            case 'hero':
            case 'comparison':
                return 'advanced';
            case 'benefits':
            case 'social-proof':
            case 'faq':
                return 'medium';
            default:
                return 'simple';
        }
    }

    private function buildEmergencyLandingHtml(array $product, array $analysis, array $structure): string
    {
        $title = htmlspecialchars((string)($product['title'] ?? $product['name'] ?? 'Product'), ENT_QUOTES, 'UTF-8');
        $price = htmlspecialchars((string)($product['sale_price'] ?? $product['price'] ?? ''), ENT_QUOTES, 'UTF-8');
        $description = htmlspecialchars(strip_tags((string)($product['short_description'] ?? $product['description'] ?? '')), ENT_QUOTES, 'UTF-8');
        $hero = is_array($analysis['hero'] ?? null) ? $analysis['hero'] : [];
        $headline = htmlspecialchars((string)($hero['headline'] ?? $title), ENT_QUOTES, 'UTF-8');
        $subheadline = htmlspecialchars((string)($hero['subheadline'] ?? $description), ENT_QUOTES, 'UTF-8');
        $cta = htmlspecialchars((string)($hero['cta'] ?? 'اطلب الآن'), ENT_QUOTES, 'UTF-8');
        $primary = htmlspecialchars((string)(($structure['visual_system']['primary_color'] ?? $analysis['visual_system']['primary_color'] ?? '#f97316')), ENT_QUOTES, 'UTF-8');

        return '<!DOCTYPE html><html lang="ar" dir="rtl"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>'
            . $title
            . '</title><style>body{margin:0;font-family:Tahoma,Arial,sans-serif;background:#f8fafc;color:#0f172a}main{max-width:960px;margin:0 auto;padding:32px 18px}section{background:#fff;border:1px solid #e2e8f0;border-radius:24px;padding:28px;margin-bottom:18px;box-shadow:0 12px 30px rgba(15,23,42,.06)}h1,h2{margin:0 0 12px}p{line-height:1.9;color:#475569}.cta{display:inline-flex;align-items:center;justify-content:center;padding:14px 22px;border-radius:999px;background:'
            . $primary
            . ';color:#fff;text-decoration:none;font-weight:700}.price{display:inline-block;margin-top:12px;padding:8px 14px;border-radius:999px;background:#fff7ed;color:#9a3412;font-weight:700}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.card{padding:18px;border-radius:18px;background:#f8fafc;border:1px solid #e2e8f0}</style></head><body><main><section><h1>'
            . $headline
            . '</h1><p>'
            . $subheadline
            . '</p><a href="#lp-order-section" class="cta" data-lp-order="1">'
            . $cta
            . '</a>'
            . ($price !== '' ? '<div class="price">' . $price . '</div>' : '')
            . '</section><section><h2>لماذا هذا المنتج؟</h2><div class="grid"><div class="card">جودة أفضل في العرض والنصوص.</div><div class="card">صفحة سريعة ومهيأة للموبايل.</div><div class="card">دعوة واضحة للشراء وزيادة التحويل.</div></div></section><section id="lp-order-section"><h2>اطلب الآن</h2><p>هذه نسخة طوارئ ذكية تم توليدها للحفاظ على استقرار المسار. يمكنك الآن تحسينها من داخل الاستوديو.</p><iframe src="{{ORDER_FORM}}?theme=light&color=%23f97316" data-lp-order-frame="1" style="width:100%;min-height:760px;border:none;border-radius:16px;" loading="lazy" title="Order Form" sandbox="allow-forms allow-scripts allow-same-origin"></iframe></section></main></body></html>';
    }

    private function applyQuickStudioEdits(string $html, string $message, array $product, array $page = []): ?string
    {
        $html = trim($html);
        if ($html === '') {
            return null;
        }

        $lower = function_exists('mb_strtolower') ? mb_strtolower($message, 'UTF-8') : strtolower($message);
        $updated = $html;
        $changed = false;

        if (strpos($lower, 'تجوال') !== false || strpos($lower, 'tajawal') !== false || strpos($lower, 'tajwel') !== false) {
            $updated = $this->applyGlobalFontToHtml($updated, 'Tajawal', 'https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700;800&display=swap');
            $changed = true;
        }

        if (
            strpos($lower, 'صور المنتج') !== false
            || strpos($lower, 'صورة المنتج') !== false
            || strpos($lower, 'product image') !== false
            || strpos($lower, 'product images') !== false
        ) {
            $productImages = $this->resolveProductImageUrls($product, $page);
            if (!empty($productImages) && strpos($updated, 'lp-product-gallery') === false) {
                $updated = $this->injectProductImageSection($updated, $productImages, (string)($product['title'] ?? $product['name'] ?? ''));
                $changed = true;
            }
        }

        if (
            strpos($lower, 'صندوق الطلب') !== false
            || strpos($lower, 'order box') !== false
            || strpos($lower, 'order form') !== false
            || strpos($lower, 'نموذج الطلب') !== false
        ) {
            $updated = $this->injectOrderBoxSection(
                $updated,
                (strpos($lower, 'اسلام') !== false || strpos($lower, 'islamic') !== false)
            );
            $changed = true;
        }

        if (
            strpos($lower, 'الاسئلة الشائعة') !== false
            || strpos($lower, 'الأسئلة الشائعة') !== false
            || strpos($lower, 'faq') !== false
            || strpos($lower, 'accordion') !== false
        ) {
            $updated = $this->injectFaqAccordionSection($updated);
            $changed = true;
        }

        if (
            strpos($lower, 'algerian cod market') !== false
            || strpos($lower, 'cod market') !== false
            || strpos($lower, 'الدزاير') !== false
            || strpos($lower, 'الجزائري') !== false
            || strpos($lower, 'الجزاير') !== false
            || strpos($lower, 'conversion-focused') !== false
            || strpos($lower, 'persuasive') !== false
            || strpos($lower, 'تحسين النصوص') !== false
            || strpos($lower, 'لهجة') !== false
        ) {
            $updated = $this->applyAlgerianCodCopyBoost($updated);
            $changed = true;
        }

        return $changed ? $updated : null;
    }

    private function applyGlobalFontToHtml(string $html, string $fontName, string $fontUrl): string
    {
        $fontNameEsc = htmlspecialchars($fontName, ENT_QUOTES, 'UTF-8');
        $fontUrlEsc = htmlspecialchars($fontUrl, ENT_QUOTES, 'UTF-8');
        $fontBlock = '<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link rel="stylesheet" href="' . $fontUrlEsc . '"><style id="lp-font-override">body,button,input,select,textarea,h1,h2,h3,h4,h5,h6{font-family:\'' . $fontNameEsc . '\',sans-serif !important;}</style>';

        $html = preg_replace('/<style id="lp-font-override">[\s\S]*?<\/style>/i', '', $html);

        if (stripos($html, '</head>') !== false) {
            return preg_replace('/<\/head>/i', $fontBlock . '</head>', $html, 1) ?: ($fontBlock . $html);
        }

        return $fontBlock . $html;
    }

    private function injectProductImageSection(string $html, array $imageUrls, string $title): string
    {
        $cards = '';
        foreach (array_slice($imageUrls, 0, 4) as $imageUrl) {
            $cards .= '<img src="'
                . htmlspecialchars($imageUrl, ENT_QUOTES, 'UTF-8')
                . '" alt="" style="max-width:100%;width:min(260px,100%);border-radius:22px;box-shadow:0 18px 36px rgba(15,23,42,.12);background:#fff;">';
        }

        $section = '<section class="lp-product-gallery" style="max-width:960px;margin:0 auto 18px;background:#fff;border:1px solid #e2e8f0;border-radius:24px;padding:24px;box-shadow:0 12px 30px rgba(15,23,42,.06);text-align:center;"><h2 style="margin:0 0 14px;">'
            . htmlspecialchars($title !== '' ? $title : 'صور المنتج', ENT_QUOTES, 'UTF-8')
            . '</h2><div style="display:flex;flex-wrap:wrap;justify-content:center;gap:14px;">'
            . $cards
            . '</div></section>';

        if (stripos($html, '<main') !== false) {
            return preg_replace('/(<main\b[^>]*>)/i', '$1' . $section, $html, 1) ?: ($section . $html);
        }

        if (stripos($html, '<body') !== false) {
            return preg_replace('/(<body\b[^>]*>)/i', '$1' . $section, $html, 1) ?: ($section . $html);
        }

        return $section . $html;
    }

    private function injectOrderBoxSection(string $html, bool $isIslamicTheme): string
    {
        if (strpos($html, 'lp-smart-order-box') !== false || strpos($html, 'data-lp-order-frame') !== false) {
            return $html;
        }

        $bg = $isIslamicTheme
            ? 'linear-gradient(135deg,#0f5132,#14532d 60%,#166534);background-image:radial-gradient(circle at top right,rgba(255,255,255,.12),transparent 28%),radial-gradient(circle at bottom left,rgba(251,191,36,.14),transparent 26%);'
            : 'linear-gradient(135deg,#fff7ed,#ffffff);';

        $section = '<section class="lp-smart-order-box" id="lp-order-section" style="max-width:980px;margin:0 auto 18px;border-radius:28px;padding:26px;'
            . $bg
            . 'color:' . ($isIslamicTheme ? '#ffffff' : '#0f172a') . ';box-shadow:0 18px 40px rgba(15,23,42,.10);">'
            . '<div style="display:grid;grid-template-columns:1.1fr .9fr;gap:20px;align-items:start;">'
            . '<div><div style="font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;opacity:.78;margin-bottom:10px;">'
            . 'COD CHECKOUT</div><h2 style="margin:0 0 10px;font-size:30px;">أكمل طلبك الآن وخلص عند الاستلام</h2>'
            . '<p style="margin:0;line-height:1.9;opacity:.92;">عبّي معلوماتك في أقل من دقيقة، وفريقنا يتصل بك بسرعة لتأكيد الطلب والتوصيل داخل الجزائر.</p>'
            . '<div style="display:flex;flex-wrap:wrap;gap:10px;margin-top:16px;"><span style="padding:8px 12px;border-radius:999px;background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.18);">تأكيد سريع</span><span style="padding:8px 12px;border-radius:999px;background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.18);">الدفع عند الاستلام</span><span style="padding:8px 12px;border-radius:999px;background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.18);">توصيل موثوق</span></div></div>'
            . '<div style="background:#fff;border-radius:22px;padding:12px;box-shadow:0 14px 30px rgba(15,23,42,.12);"><iframe src="{{ORDER_FORM}}?theme=light&color=%23f97316" data-lp-order-frame="1" style="width:100%;min-height:760px;border:none;border-radius:16px;background:#fff;" loading="lazy" title="Order Form" sandbox="allow-forms allow-scripts allow-same-origin"></iframe></div>'
            . '</div></section>';

        if (stripos($html, '</main>') !== false) {
            return preg_replace('/<\/main>/i', $section . '</main>', $html, 1) ?: ($html . $section);
        }

        if (stripos($html, '</body>') !== false) {
            return preg_replace('/<\/body>/i', $section . '</body>', $html, 1) ?: ($html . $section);
        }

        return $html . $section;
    }

    private function injectFaqAccordionSection(string $html): string
    {
        if (strpos($html, 'lp-faq-accordion') !== false) {
            return $html;
        }

        $section = '<section class="lp-faq-accordion" style="max-width:960px;margin:0 auto 18px;background:#fff;border:1px solid #e2e8f0;border-radius:26px;padding:24px;box-shadow:0 12px 30px rgba(15,23,42,.06);">'
            . '<h2 style="margin:0 0 14px;">الأسئلة الشائعة</h2>'
            . '<div style="display:grid;gap:12px;">'
            . '<details open style="border:1px solid #e2e8f0;border-radius:18px;padding:14px 16px;"><summary style="cursor:pointer;font-weight:800;">هل يوجد الدفع عند الاستلام؟</summary><div style="margin-top:10px;color:#475569;line-height:1.8;">نعم، تقدر تطلب الآن وتخلص غير كي يوصلك الطلب ونأكدوه معك هاتفيًا قبل الشحن.</div></details>'
            . '<details style="border:1px solid #e2e8f0;border-radius:18px;padding:14px 16px;"><summary style="cursor:pointer;font-weight:800;">في كم يوصل الطلب؟</summary><div style="margin-top:10px;color:#475569;line-height:1.8;">مدة التوصيل تختلف حسب الولاية، لكن فريقنا يراجع معك كل التفاصيل مباشرة بعد تأكيد الطلب.</div></details>'
            . '<details style="border:1px solid #e2e8f0;border-radius:18px;padding:14px 16px;"><summary style="cursor:pointer;font-weight:800;">كيف نضمن جودة المنتج؟</summary><div style="margin-top:10px;color:#475569;line-height:1.8;">نركز على الشرح الواضح والصور الحقيقية وتأكيد الطلب قبل الإرسال حتى تكون الصورة كاملة قبل الشراء.</div></details>'
            . '</div></section>';

        if (stripos($html, '</main>') !== false) {
            return preg_replace('/<\/main>/i', $section . '</main>', $html, 1) ?: ($html . $section);
        }

        if (stripos($html, '</body>') !== false) {
            return preg_replace('/<\/body>/i', $section . '</body>', $html, 1) ?: ($html . $section);
        }

        return $html . $section;
    }

    private function applyAlgerianCodCopyBoost(string $html): string
    {
        $replacements = [
            '/>\s*(Shop Now|Buy Now|Add to Cart)\s*</iu' => '>اطلب الآن وخلص عند الاستلام<',
            '/>\s*اطلب الآن\s*</u' => '>اطلب الآن وخلص عند الاستلام<',
            '/>\s*Order Now\s*</iu' => '>أكّد طلبك الآن<',
        ];

        foreach ($replacements as $pattern => $replacement) {
            $html = preg_replace($pattern, $replacement, $html) ?? $html;
        }

        if (strpos($html, 'lp-cod-trust-bar') === false) {
            $trustBar = '<section class="lp-cod-trust-bar" style="max-width:960px;margin:0 auto 18px;background:linear-gradient(135deg,#fff7ed,#ffffff);border:1px solid #fed7aa;border-radius:24px;padding:18px 22px;box-shadow:0 12px 30px rgba(249,115,22,.08);">'
                . '<div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between;">'
                . '<strong style="font-size:18px;">عرض مناسب لسوق الجزائر مع خلاص عند الاستلام</strong>'
                . '<div style="display:flex;flex-wrap:wrap;gap:10px;"><span style="padding:8px 12px;border-radius:999px;background:#fff;border:1px solid #fdba74;">توصيل داخل الجزائر</span><span style="padding:8px 12px;border-radius:999px;background:#fff;border:1px solid #fdba74;">تأكيد سريع للطلب</span><span style="padding:8px 12px;border-radius:999px;background:#fff;border:1px solid #fdba74;">دفع عند الاستلام</span></div>'
                . '</div></section>';

            if (stripos($html, '<main') !== false) {
                $html = preg_replace('/(<main\b[^>]*>)/i', '$1' . $trustBar, $html, 1) ?: ($trustBar . $html);
            } else {
                $html = $trustBar . $html;
            }
        }

        return $html;
    }

    private function resolveProductImageUrls(array $product, array $page = []): array
    {
        $images = [];

        foreach (['featured_image', 'image'] as $field) {
            if (!empty($product[$field]) && is_string($product[$field])) {
                $images[] = $this->normalizeMediaUrl($product[$field]);
            }
        }

        if (!empty($product['images']) && is_array($product['images'])) {
            foreach ($product['images'] as $item) {
                if (is_string($item) && trim($item) !== '') {
                    $images[] = $this->normalizeMediaUrl($item);
                    continue;
                }

                if (is_array($item)) {
                    foreach (['url', 'path', 'image', 'src'] as $key) {
                        if (!empty($item[$key]) && is_string($item[$key])) {
                            $images[] = $this->normalizeMediaUrl($item[$key]);
                            break;
                        }
                    }
                }
            }
        }

        if (!empty($page['source_image']) && is_string($page['source_image'])) {
            $images[] = $this->normalizeMediaUrl($page['source_image']);
        }

        $images = array_values(array_filter(array_unique($images)));

        return $images;
    }

    private function normalizeMediaUrl(string $path): string
    {
        $path = trim($path);
        if ($path === '') {
            return '';
        }

        if (preg_match('/^(https?:)?\/\//i', $path) || strpos($path, 'data:') === 0) {
            return $path;
        }

        return '/' . ltrim($path, '/');
    }

    private function stringifyValue($value): string
    {
        if (is_array($value)) {
            foreach (['text', 'label', 'title', 'value', 'name', 0] as $key) {
                if (array_key_exists($key, $value) && !is_array($value[$key])) {
                    return trim((string)$value[$key]);
                }
            }

            $parts = [];
            foreach ($value as $item) {
                $part = $this->stringifyValue($item);
                if ($part !== '') {
                    $parts[] = $part;
                }
            }

            return implode(' • ', array_slice($parts, 0, 3));
        }

        if (is_object($value)) {
            return $this->stringifyValue((array)$value);
        }

        return trim((string)$value);
    }

    private function buildFastVariants(array $page, array $product, array $structure): array
    {
        $baseHtml = trim((string)($page['html_content'] ?? ''));
        if ($baseHtml === '') {
            $baseHtml = $this->buildEmergencyLandingHtml($product, (array)($page['analysis_json'] ?? []), $structure);
        }

        $concepts = array_values(array_filter((array)(($page['agent_trace']['concepts'] ?? [])), static function ($concept): bool {
            return is_array($concept) && !empty($concept['name']);
        }));

        $configs = [
            [
                'name' => (string)($concepts[0]['name'] ?? 'زاوية النتيجة'),
                'angle' => (string)($concepts[0]['angle'] ?? 'إبراز النتيجة النهائية بسرعة ووضوح.'),
                'hook' => (string)($concepts[0]['hook'] ?? 'النتيجة التي يريدها العميل من أول نظرة.'),
                'cta' => 'اطلب الآن',
                'color' => '#f97316',
                'score' => 90,
            ],
            [
                'name' => (string)($concepts[1]['name'] ?? 'زاوية المشكلة'),
                'angle' => (string)($concepts[1]['angle'] ?? 'ابدأ بالمشكلة ثم قدم الحل بسرعة.'),
                'hook' => (string)($concepts[1]['hook'] ?? 'حل مباشر لمشكلة مزعجة ومتكررة.'),
                'cta' => 'اكتشف الحل الآن',
                'color' => '#0f766e',
                'score' => 87,
            ],
            [
                'name' => (string)($concepts[2]['name'] ?? 'زاوية الثقة'),
                'angle' => (string)($concepts[2]['angle'] ?? 'اعرض الثقة والضمان وطمأنة العميل.'),
                'hook' => (string)($concepts[2]['hook'] ?? 'ثقة أعلى وتجربة طلب أوضح.'),
                'cta' => 'احجز عرضك الآن',
                'color' => '#2563eb',
                'score' => 85,
            ],
        ];

        $variants = [];
        foreach ($configs as $index => $config) {
            $variants[] = [
                'id' => 'variant_' . ($index + 1),
                'name' => $config['name'],
                'angle' => $config['angle'],
                'hook' => $config['hook'],
                'score' => $config['score'],
                'html' => $this->decorateVariantHtml($baseHtml, $config),
                'scorecard' => [
                    'global_score' => $config['score'],
                    'cta_score' => max(78, $config['score'] - 4),
                ],
                'evaluation' => [
                    'score' => $config['score'],
                    'issues' => [],
                ],
            ];
        }

        return [
            'seed' => [
                'html' => $baseHtml,
            ],
            'variants' => $variants,
        ];
    }

    private function decorateVariantHtml(string $html, array $config): string
    {
        $cta = htmlspecialchars((string)$config['cta'], ENT_QUOTES, 'UTF-8');
        $color = htmlspecialchars((string)$config['color'], ENT_QUOTES, 'UTF-8');
        $name = htmlspecialchars((string)$config['name'], ENT_QUOTES, 'UTF-8');
        $hook = htmlspecialchars((string)$config['hook'], ENT_QUOTES, 'UTF-8');

        $style = '<style id="lp-variant-override">:root{--lp-variant-accent:' . $color . ';}.lp-variant-ribbon{max-width:960px;margin:18px auto 0;padding:12px 18px;border-radius:18px;background:' . $color . ';color:#fff;font-weight:800;text-align:center;box-shadow:0 14px 30px rgba(15,23,42,.12)}[data-lp-order="1"],.cta,button[type="submit"]{background:' . $color . ' !important;border-color:' . $color . ' !important;color:#fff !important;}</style>';
        $ribbon = '<div class="lp-variant-ribbon">' . $name . ' — ' . $hook . '</div>';

        $updated = preg_replace('/<style id="lp-variant-override">[\s\S]*?<\/style>/i', '', $html);
        $updated = preg_replace('/<div class="lp-variant-ribbon">[\s\S]*?<\/div>/i', '', (string)$updated);
        $updated = str_replace(['اطلب الآن', 'Shop Now', 'Buy Now', 'Add to Cart'], $cta, (string)$updated);

        if (stripos((string)$updated, '</head>') !== false) {
            $updated = preg_replace('/<\/head>/i', $style . '</head>', (string)$updated, 1) ?: ((string)$updated);
        } else {
            $updated = $style . (string)$updated;
        }

        if (stripos((string)$updated, '<body') !== false) {
            $updated = preg_replace('/(<body\b[^>]*>)/i', '$1' . $ribbon, (string)$updated, 1) ?: ($ribbon . (string)$updated);
        } else {
            $updated = $ribbon . (string)$updated;
        }

        return (string)$updated;
    }

    private function fetchCompetitorHtml(string $url): string
    {
        $parsedUrl = parse_url($url);
        $scheme = strtolower((string)($parsedUrl['scheme'] ?? ''));
        if (!in_array($scheme, ['http', 'https'], true)) {
            throw new \RuntimeException(__('landing.competitor_invalid_url', 'Please enter a valid competitor URL.'));
        }

        $hostname = strtolower((string)($parsedUrl['host'] ?? ''));
        if ($hostname === '') {
            throw new \RuntimeException(__('landing.competitor_invalid_url', 'Please enter a valid competitor URL.'));
        }

        $ip = gethostbyname($hostname);
        if ($ip === $hostname || !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
            throw new \RuntimeException(__('lp.ssrf_blocked', 'Access to this URL is not allowed.'));
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => false,
            CURLOPT_TIMEOUT => 12,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_SSL_VERIFYHOST => 2,
            CURLOPT_HTTPHEADER => [
                'User-Agent: Mozilla/5.0 (compatible; MTEngine/1.0)',
                'Accept: text/html,application/xhtml+xml',
            ],
        ]);
        $response = curl_exec($ch);
        $httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlError = curl_error($ch);
        curl_close($ch);

        if ($response === false || $httpCode < 200 || $httpCode >= 300) {
            throw new \RuntimeException(__('landing.competitor_fetch_failed', 'Failed to fetch competitor page.') . ($curlError ? ' ' . $curlError : ''));
        }

        $html = trim((string)$response);
        if ($html === '') {
            throw new \RuntimeException(__('landing.competitor_fetch_failed', 'Failed to fetch competitor page.'));
        }

        $html = preg_replace('/<script\b[^>]*>.*?<\/script>/is', '', $html) ?? $html;
        $html = strip_tags($html);
        $html = preg_replace('/\s+/', ' ', $html) ?? $html;

        return mb_substr($html, 0, 12000);
    }

    private function absoluteAssetUrl(string $path): string
    {
        if (preg_match('#^https?://#i', $path)) {
            return $path;
        }

        $base = rtrim(Env::get('APP_URL', ''), '/');
        return $base !== '' ? $base . '/' . ltrim($path, '/') : $path;
    }
}
