<?php

namespace Core\App\Services;

class LandingImageAnalysisService
{
    private AiService $ai;

    public function __construct(?AiService $ai = null)
    {
        $this->ai = $ai ?: AiService::fromActiveProvider();
    }

    public function analyze(array $product, string $imageDiskPath): array
    {
        $dialectInstruction = $this->ai->buildDialectInstruction('ar');
        $productTitle = (string)($product['title'] ?? $product['name'] ?? 'Product');
        $productDescription = trim(strip_tags((string)($product['short_description'] ?? $product['description'] ?? '')));
        $productPrice = (string)($product['sale_price'] ?? $product['price'] ?? '');
        $currency = (string)($product['currency'] ?? 'DZD');

        $system = <<<PROMPT
You are a senior UI reverse-engineering agent and conversion-focused landing-page strategist.
Analyze the uploaded landing page screenshot/design and return strict JSON only.
No markdown fences, no prose, no explanations.
PROMPT;

        $prompt = <<<PROMPT
{$dialectInstruction}

Analyze this screenshot/design and reconstruct its landing-page intent as structured data.
The linked product is:
- title: {$productTitle}
- description: {$productDescription}
- price: {$productPrice} {$currency}

Return a valid JSON object using this schema exactly:
{
  "page_goal": "string",
  "layout_style": "string",
  "visual_system": {
    "direction": "rtl or ltr",
    "primary_color": "#rrggbb",
    "secondary_color": "#rrggbb",
    "accent_color": "#rrggbb",
    "background_color": "#rrggbb",
    "text_color": "#rrggbb",
    "font_style": "string",
    "mood": "string"
  },
  "hero": {
    "headline": "string",
    "subheadline": "string",
    "badge": "string",
    "media": "image or product or illustration or mockup",
    "cta": {
      "text": "string",
      "style": "primary or secondary"
    },
    "notes": ["string"]
  },
  "sections": [
    {
      "type": "hero|banner|benefits|features|gallery|pricing|testimonials|faq|guarantee|cta|checkout|social-proof|stats",
      "label": "string",
      "headline": "string",
      "subheadline": "string",
      "purpose": "string",
      "items": [],
      "cta": {
        "text": "string",
        "style": "primary or secondary"
      },
      "background": "string",
      "notes": ["string"]
    }
  ],
  "copy_elements": {
    "pain_points": ["string"],
    "benefits": ["string"],
    "trust_signals": ["string"],
    "offer": "string",
    "urgency": "string"
  },
  "cta_candidates": ["string"],
  "detected_text": ["string"],
  "conversion_notes": ["string"]
}

Rules:
1. Use the screenshot as the source of truth for layout and visual style.
2. If text in the screenshot is cut or partially unreadable, infer it carefully and mark uncertainty in notes.
3. Detect the likely reading direction.
4. Extract only sections that truly appear in the screenshot.
5. Keep all arrays compact and relevant.
6. Output pure JSON only.
PROMPT;

        $response = $this->ai->visionGenerate($prompt, [
            ['path' => $imageDiskPath],
        ], [
            'system' => $system,
            'max_tokens' => 3200,
            'temperature' => 0.2,
        ]);

        try {
            $decoded = $this->extractJson($response);
            return is_array($decoded) ? $this->normalizeAnalysis($decoded, $product) : $this->fallbackAnalysis($product);
        } catch (\Throwable $e) {
            try {
                $repaired = $this->repairJsonResponse($response);
                return $this->normalizeAnalysis($repaired, $product);
            } catch (\Throwable $repairFailure) {
                return $this->fallbackAnalysis($product);
            }
        }
    }

    private function extractJson(string $raw): array
    {
        $raw = trim($raw);
        $raw = preg_replace('/```(?:json)?/i', '', $raw);
        $raw = trim((string)$raw);

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

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

        throw new \RuntimeException(__('landing.image_analysis_invalid', 'The AI image analysis did not return valid JSON.'));
    }

    private function repairJsonResponse(string $raw): array
    {
        $prompt = <<<PROMPT
Convert the following model output into strict valid JSON only.
Do not explain anything. Do not add markdown fences.
Preserve the original meaning but fix syntax, trailing commas, comments, invalid quotes, and any prose around the JSON.

Output:
{$raw}
PROMPT;

        $fixed = $this->ai->generate($prompt, [
            'max_tokens' => 2800,
            'temperature' => 0.1,
        ]);

        $decoded = $this->extractJson($fixed);
        if (!is_array($decoded)) {
            throw new \RuntimeException(__('landing.image_analysis_invalid', 'The AI image analysis did not return valid JSON.'));
        }

        return $decoded;
    }

    private function normalizeAnalysis(array $analysis, array $product): array
    {
        $analysis['page_goal'] = trim((string)($analysis['page_goal'] ?? 'product-conversion'));
        $analysis['layout_style'] = trim((string)($analysis['layout_style'] ?? 'modern-product'));

        if (!isset($analysis['visual_system']) || !is_array($analysis['visual_system'])) {
            $analysis['visual_system'] = [];
        }

        $analysis['visual_system'] = [
            'direction' => in_array($analysis['visual_system']['direction'] ?? 'rtl', ['rtl', 'ltr'], true)
                ? (string)$analysis['visual_system']['direction']
                : 'rtl',
            'primary_color' => $this->normalizeHex($analysis['visual_system']['primary_color'] ?? '#111827'),
            'secondary_color' => $this->normalizeHex($analysis['visual_system']['secondary_color'] ?? '#1d4ed8'),
            'accent_color' => $this->normalizeHex($analysis['visual_system']['accent_color'] ?? '#f59e0b'),
            'background_color' => $this->normalizeHex($analysis['visual_system']['background_color'] ?? '#ffffff'),
            'text_color' => $this->normalizeHex($analysis['visual_system']['text_color'] ?? '#111827'),
            'font_style' => trim((string)($analysis['visual_system']['font_style'] ?? 'modern')),
            'mood' => trim((string)($analysis['visual_system']['mood'] ?? 'clean')),
        ];

        if (!isset($analysis['hero']) || !is_array($analysis['hero'])) {
            $analysis['hero'] = [];
        }

        $analysis['hero'] = [
            'headline' => trim((string)($analysis['hero']['headline'] ?? ($product['title'] ?? $product['name'] ?? 'منتج مميز'))),
            'subheadline' => trim((string)($analysis['hero']['subheadline'] ?? strip_tags((string)($product['short_description'] ?? '')))),
            'badge' => trim((string)($analysis['hero']['badge'] ?? '')),
            'media' => trim((string)($analysis['hero']['media'] ?? 'product')),
            'cta' => [
                'text' => trim((string)($analysis['hero']['cta']['text'] ?? 'اطلب الآن')),
                'style' => trim((string)($analysis['hero']['cta']['style'] ?? 'primary')),
            ],
            'notes' => $this->normalizeStringList($analysis['hero']['notes'] ?? []),
        ];

        $analysis['sections'] = $this->normalizeSections($analysis['sections'] ?? []);
        $analysis['copy_elements'] = [
            'pain_points' => $this->normalizeStringList($analysis['copy_elements']['pain_points'] ?? []),
            'benefits' => $this->normalizeStringList($analysis['copy_elements']['benefits'] ?? []),
            'trust_signals' => $this->normalizeStringList($analysis['copy_elements']['trust_signals'] ?? []),
            'offer' => trim((string)($analysis['copy_elements']['offer'] ?? '')),
            'urgency' => trim((string)($analysis['copy_elements']['urgency'] ?? '')),
        ];
        $analysis['cta_candidates'] = $this->normalizeStringList($analysis['cta_candidates'] ?? []);
        $analysis['detected_text'] = $this->normalizeStringList($analysis['detected_text'] ?? []);
        $analysis['conversion_notes'] = $this->normalizeStringList($analysis['conversion_notes'] ?? []);

        return $analysis;
    }

    private function normalizeSections($sections): array
    {
        if (!is_array($sections)) {
            return [];
        }

        $normalized = [];
        foreach ($sections as $section) {
            if (!is_array($section)) {
                continue;
            }

            $normalized[] = [
                'type' => trim((string)($section['type'] ?? 'features')),
                'label' => trim((string)($section['label'] ?? 'Section')),
                'headline' => trim((string)($section['headline'] ?? '')),
                'subheadline' => trim((string)($section['subheadline'] ?? '')),
                'purpose' => trim((string)($section['purpose'] ?? '')),
                'items' => is_array($section['items'] ?? null) ? $section['items'] : [],
                'cta' => [
                    'text' => trim((string)($section['cta']['text'] ?? '')),
                    'style' => trim((string)($section['cta']['style'] ?? 'primary')),
                ],
                'background' => trim((string)($section['background'] ?? '')),
                'notes' => $this->normalizeStringList($section['notes'] ?? []),
            ];
        }

        return $normalized;
    }

    private function normalizeStringList($items): array
    {
        if (!is_array($items)) {
            return [];
        }

        $result = [];
        foreach ($items as $item) {
            $value = trim((string)$item);
            if ($value !== '') {
                $result[] = $value;
            }
        }

        return array_values(array_unique($result));
    }

    private function normalizeHex($color): string
    {
        $color = trim((string)$color);
        if (!preg_match('/^#?[0-9a-fA-F]{6}$/', $color)) {
            return '#111827';
        }
        return strpos($color, '#') === 0 ? $color : '#' . $color;
    }

    private function fallbackAnalysis(array $product): array
    {
        return $this->normalizeAnalysis([
            'page_goal' => 'product-conversion',
            'layout_style' => 'modern-product',
            'visual_system' => [
                'direction' => 'rtl',
                'primary_color' => '#111827',
                'secondary_color' => '#1d4ed8',
                'accent_color' => '#f59e0b',
                'background_color' => '#ffffff',
                'text_color' => '#111827',
                'font_style' => 'modern',
                'mood' => 'clean',
            ],
            'hero' => [
                'headline' => $product['title'] ?? $product['name'] ?? 'منتج مميز',
                'subheadline' => strip_tags((string)($product['short_description'] ?? '')),
                'badge' => '',
                'media' => 'product',
                'cta' => ['text' => 'اطلب الآن', 'style' => 'primary'],
                'notes' => [],
            ],
            'sections' => [],
            'copy_elements' => [
                'pain_points' => [],
                'benefits' => [],
                'trust_signals' => [],
                'offer' => '',
                'urgency' => '',
            ],
            'cta_candidates' => ['اطلب الآن'],
            'detected_text' => [],
            'conversion_notes' => ['Fallback analysis used because the raw model output was not valid JSON.'],
        ], $product);
    }
}
