<?php

namespace Core\App\Services;

class LandingPageAgentService
{
    private AiService $ai;
    private AiLandingPageService $landingPages;

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

    public function buildFromStructure(array $product, array $structure, ?string $existingHtml = null, array $options = []): array
    {
        $productCard = $this->buildProductCard($product, $structure);
        $destinations = $this->buildDestinations($productCard, $structure);
        $concepts = $this->generateConcepts($productCard, $structure);
        $selectedConcept = trim((string)($options['selected_concept'] ?? ''));
        $lockedSections = $this->extractLockedSections($structure);
        $sectionBlueprint = $this->planSections($productCard, $structure, $concepts, $selectedConcept);
        $scorecard = $this->scoreOpportunity($productCard, $structure, $concepts, $sectionBlueprint);
        $plan = $this->plan($product, $structure, $concepts, $sectionBlueprint, $scorecard);
        $draftHtml = $this->landingPages->generateFromStructure($product, $structure, [
            'plan' => $plan,
            'existing_html' => $existingHtml,
            'concepts' => $concepts,
            'section_blueprint' => $sectionBlueprint,
            'scorecard' => $scorecard,
            'selected_concept' => $selectedConcept,
            'locked_sections' => $lockedSections,
        ]);

        $evaluation = $this->landingPages->evaluateGeneratedHtml($product, $structure, $draftHtml);
        $finalHtml = $draftHtml;
        $improvement = [];

        $needsImprove = ((int)($evaluation['score'] ?? 0) < 88) || !empty($evaluation['issues']);
        if ($needsImprove) {
            $finalHtml = $this->landingPages->improveGeneratedHtml($product, $structure, $draftHtml, $evaluation, $plan);
            $improvement = $this->landingPages->evaluateGeneratedHtml($product, $structure, $finalHtml);
        }

        return [
            'product_card' => $productCard,
            'destinations' => $destinations,
            'concepts' => $concepts,
            'section_blueprint' => $sectionBlueprint,
            'scorecard' => $scorecard,
            'locked_sections' => $lockedSections,
            'selected_concept' => $selectedConcept,
            'plan' => $plan,
            'draft_evaluation' => $evaluation,
            'final_evaluation' => $improvement ?: $evaluation,
            'html' => $finalHtml,
        ];
    }

    public function buildVariants(array $product, array $structure, int $limit = 3): array
    {
        $seed = $this->buildFromStructure($product, $structure, null);
        $concepts = array_slice($seed['concepts'] ?? [], 0, max(1, $limit));
        $variants = [];

        foreach ($concepts as $index => $concept) {
            $conceptName = trim((string)($concept['name'] ?? 'Variant ' . ($index + 1)));
            $result = $this->buildFromStructure($product, $structure, null, [
                'selected_concept' => $conceptName,
            ]);

            $variants[] = [
                'id' => 'variant_' . ($index + 1),
                'name' => $conceptName,
                'angle' => (string)($concept['angle'] ?? ''),
                'hook' => (string)($concept['hook'] ?? ''),
                'score' => (int)($result['final_evaluation']['score'] ?? $result['scorecard']['global_score'] ?? 0),
                'html' => $result['html'],
                'scorecard' => $result['scorecard'] ?? [],
                'evaluation' => $result['final_evaluation'] ?? [],
            ];
        }

        usort($variants, static fn(array $a, array $b): int => ($b['score'] ?? 0) <=> ($a['score'] ?? 0));

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

    public function analyzeCompetitor(array $product, string $url, string $html): array
    {
        $prompt = <<<PROMPT
Analyze this competitor landing page and compare it with our product opportunity.
Return JSON only:
{
  "url": "string",
  "global_score": 0,
  "copy_score": 0,
  "design_score": 0,
  "cta_score": 0,
  "trust_score": 0,
  "mobile_score": 0,
  "executive_summary": "string",
  "strengths": ["string"],
  "weaknesses": ["string"],
  "gaps_we_can_exploit": ["string"],
  "recommended_sections": ["string"],
  "recommended_angles": ["string"],
  "hooks_to_try": ["string"],
  "cta_opportunities": ["string"],
  "trust_opportunities": ["string"],
  "ux_observations": ["string"],
  "offer_observations": ["string"],
  "quick_wins": ["string"],
  "lp_strategy": "string"
}

Our product:
{$this->toJson($product)}

Competitor URL:
{$url}

Competitor HTML excerpt:
{$html}
PROMPT;

        return $this->ai->generateJson($prompt, [
            'max_tokens' => 1800,
            'temperature' => 0.25,
        ]);
    }

    public function plan(array $product, array $structure, array $concepts = [], array $sectionBlueprint = [], array $scorecard = []): array
    {
        $prompt = <<<PROMPT
Create a compact JSON build plan for a landing page.
Return JSON only:
{
  "page_positioning": "string",
  "section_order": ["hero", "features"],
  "cta_strategy": ["string"],
  "copy_improvements": ["string"],
  "design_improvements": ["string"]
}

Product:
{$this->toJson($product)}

Structure:
{$this->toJson($structure)}

Concepts:
{$this->toJson($concepts)}

Section blueprint:
{$this->toJson($sectionBlueprint)}

Scorecard:
{$this->toJson($scorecard)}
PROMPT;

        return $this->ai->generateJson($prompt, [
            'max_tokens' => 1200,
            'temperature' => 0.2,
        ]);
    }

    private function toJson(array $data): string
    {
        return json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    }

    private function buildProductCard(array $product, array $structure): array
    {
        $prompt = <<<PROMPT
Turn the product + visual structure into a compact product-analysis card.
Return JSON only:
{
  "product_name": "string",
  "brand": "string",
  "category": "string",
  "audience": "string",
  "positioning": "string",
  "core_offer": "string",
  "visual_angle": "string",
  "palette": ["#000000"],
  "copy_seed": ["string"]
}

Product:
{$this->toJson($product)}

Structure:
{$this->toJson($structure)}
PROMPT;

        return $this->ai->generateJson($prompt, [
            'max_tokens' => 900,
            'temperature' => 0.25,
        ]);
    }

    private function buildDestinations(array $productCard, array $structure): array
    {
        $prompt = <<<PROMPT
Create destination briefs from this product analysis.
Return JSON only:
{
  "landing_page": {"title":"string","goal":"string","notes":["string"]},
  "static_ads": {"title":"string","goal":"string","notes":["string"]},
  "video_brief": {"title":"string","goal":"string","notes":["string"]},
  "ad_copy": {"title":"string","goal":"string","notes":["string"]}
}

Product card:
{$this->toJson($productCard)}

Structure:
{$this->toJson($structure)}
PROMPT;

        return $this->ai->generateJson($prompt, [
            'max_tokens' => 1200,
            'temperature' => 0.25,
        ]);
    }

    private function generateConcepts(array $productCard, array $structure): array
    {
        $prompt = <<<PROMPT
Generate 4 distinct marketing concepts for this product.
Return JSON only:
{
  "concepts": [
    {
      "name": "string",
      "angle": "string",
      "hook": "string",
      "promise": "string",
      "cta": "string",
      "mood": "string",
      "fit": "string"
    }
  ]
}

Product card:
{$this->toJson($productCard)}

Structure:
{$this->toJson($structure)}
PROMPT;

        $result = $this->ai->generateJson($prompt, [
            'max_tokens' => 1400,
            'temperature' => 0.45,
        ]);

        return $result['concepts'] ?? [];
    }

    private function planSections(array $productCard, array $structure, array $concepts, string $selectedConcept = ''): array
    {
        $selectionNote = $selectedConcept !== ''
            ? "Preferred concept to build around: {$selectedConcept}"
            : 'Choose the strongest concept yourself.';
        $prompt = <<<PROMPT
Create a landing-page section blueprint based on the strongest concept.
Return JSON only:
{
  "selected_concept": "string",
  "sections": [
    {
      "type": "string",
      "goal": "string",
      "headline": "string",
      "content_note": "string",
      "priority": "high|medium|low"
    }
  ]
}

Product card:
{$this->toJson($productCard)}

Structure:
{$this->toJson($structure)}

Concepts:
{$this->toJson($concepts)}

{$selectionNote}
PROMPT;

        return $this->ai->generateJson($prompt, [
            'max_tokens' => 1300,
            'temperature' => 0.3,
        ]);
    }

    private function scoreOpportunity(array $productCard, array $structure, array $concepts, array $sectionBlueprint): array
    {
        $prompt = <<<PROMPT
Score the landing-page opportunity.
Return JSON only:
{
  "global_score": 0,
  "copy_score": 0,
  "cta_score": 0,
  "visual_score": 0,
  "mobile_score": 0,
  "market_fit_score": 0,
  "strengths": ["string"],
  "weaknesses": ["string"],
  "quick_wins": ["string"]
}

Product card:
{$this->toJson($productCard)}

Structure:
{$this->toJson($structure)}

Concepts:
{$this->toJson($concepts)}

Section blueprint:
{$this->toJson($sectionBlueprint)}
PROMPT;

        return $this->ai->generateJson($prompt, [
            'max_tokens' => 1200,
            'temperature' => 0.2,
        ]);
    }

    private function extractLockedSections(array $structure): array
    {
        $locked = [];
        foreach (($structure['sections'] ?? []) as $section) {
            if (!is_array($section) || empty($section['locked'])) {
                continue;
            }
            $locked[] = [
                'type' => (string)($section['type'] ?? ''),
                'label' => (string)($section['label'] ?? ''),
                'headline' => (string)($section['headline'] ?? ''),
                'purpose' => (string)($section['purpose'] ?? ''),
            ];
        }
        return $locked;
    }
}
