<?php
namespace CAE\Modules\ContentEngine;

class VariableInjector
{
    /**
     * Build a flat variable map from project, topic, and page type data.
     */
    public function buildVariables(array $project, array $topic, array $pageType): array
    {
        $pageTypeRules = is_array($pageType['structure_rules'] ?? null)
            ? $this->jsonToText($pageType['structure_rules'])
            : ($pageType['structure_rules'] ?? '');

        $contentBlocks = is_array($pageType['content_blocks'] ?? null)
            ? $this->jsonToText($pageType['content_blocks'])
            : ($pageType['content_blocks'] ?? '');

        $seoRules = is_array($pageType['seo_rules'] ?? null)
            ? $this->jsonToText($pageType['seo_rules'])
            : ($pageType['seo_rules'] ?? '');

        return [
            // Project variables
            'business_name'         => $project['business_name']         ?? '',
            'website_url'           => $project['website_url']           ?? '',
            'target_audience'       => $project['target_audience']       ?? '',
            'content_intent'        => $project['content_intent']        ?? '',
            'brand_positioning'     => $project['brand_positioning']     ?? '',
            'tone_voice'            => $project['tone_voice']            ?? 'professional',
            'brand_dos'             => $project['brand_dos']             ?? '',
            'brand_donts'           => $project['brand_donts']           ?? '',
            'pov_type'              => $this->povLabel($project['pov_type'] ?? 'third_person'),
            'seo_philosophy'        => $project['seo_philosophy']        ?? '',
            'compliance_rules'      => $project['compliance_rules']      ?? 'None',
            'brand_reference_style' => $project['brand_reference_style'] ?? '',
            'cta_style'             => $project['cta_style']             ?? '',
            'no_no_words'           => $project['no_no_words']           ?? 'None',

            // Topic variables
            'title'                 => $topic['title']                   ?? '',
            'primary_keyword'       => $topic['primary_keyword']         ?? '',
            'supporting_keywords'   => $topic['supporting_keywords']     ?? '',
            'search_intent'         => $topic['search_intent']           ?? 'informational',
            'content_angle'         => $topic['content_angle']           ?? '',
            'target_word_count'     => (string)($topic['target_word_count'] ?? 1200),

            // Page type variables
            'page_type_name'        => $pageType['name']                 ?? '',
            'page_type_category'    => $pageType['category']             ?? '',
            'structure_rules'       => $pageTypeRules,
            'content_blocks'        => $contentBlocks,
            'seo_rules'             => $seoRules,
            'min_word_count'        => (string)($pageType['min_word_count'] ?? 800),
            'max_word_count'        => (string)($pageType['max_word_count'] ?? 2500),
        ];
    }

    /**
     * Replace {{variable_name}} placeholders in a template string.
     */
    public function inject(string $template, array $variables): string
    {
        foreach ($variables as $key => $value) {
            $template = str_replace('{{' . $key . '}}', (string)$value, $template);
        }
        // Remove any unresolved placeholders
        $template = preg_replace('/\{\{[a-z_]+\}\}/', '[N/A]', $template);
        return $template;
    }

    /**
     * Append non-negotiable QA requirements to the user prompt.
     * These are always included so the AI knows hard limits before it writes a single word.
     */
    public function appendQARequirements(string $userPrompt, array $variables): string
    {
        $target  = (int)($variables['target_word_count'] ?? 1200);
        $min     = (int)round($target * 0.7);
        $keyword = $variables['primary_keyword'] ?? '';

        // Estimate per-section target so the AI distributes length evenly
        $secCount = max(3, (int)round($target / 250));
        $secWords = (int)round($target / $secCount);

        return $userPrompt
            . "\n\n=== NON-NEGOTIABLE CONTENT REQUIREMENTS (violating any = automatic rejection) ===\n"
            . "1. WORD COUNT — CRITICAL: Your response MUST be exactly {$target} words (minimum {$min}).\n"
            . "   Structure your article with approximately {$secCount} main sections of ~{$secWords} words each.\n"
            . "   Write EVERY section in full — do NOT summarise, do NOT stop early, do NOT truncate.\n"
            . "   Expand with: real examples, step-by-step explanations, supporting detail, and practical tips.\n"
            . "2. READING LEVEL — 7th to 10th Grade (Flesch Reading Ease 60–80):\n"
            . "   - Use everyday words a 14-year-old would understand — avoid jargon and corporate buzzwords.\n"
            . "   - Keep most sentences under 18 words. Mix short punchy sentences (6–10 words) with medium ones.\n"
            . "   - Use active voice: 'Students learn best' NOT 'Learning is best achieved by students'.\n"
            . "   - Write like a knowledgeable teacher explaining to curious secondary school students.\n"
            . "   - No filler phrases: 'it is important to note', 'delve into', 'in today's world', 'game-changer'.\n"
            . "3. PRIMARY KEYWORD: The exact phrase \"{$keyword}\" MUST appear naturally at least 3 times — once in the opening paragraph, once in an H2 heading (or near one), and once in the closing section.\n"
            . "4. NO 'CONCLUSION' HEADING: Never use 'Conclusion' as a section heading. Replace it with a specific, action-oriented heading (e.g. 'Your Next Step', 'Get Started Today', 'What This Means for You').\n"
            . "5. OUTPUT FORMAT: Return clean HTML only — use <h1>, <h2>, <h3>, <p>, <ul>, <li>, <strong>, <em>. No markdown. No ``` code fences. No preamble text outside the article.\n"
            . "6. H1: Exactly one <h1> for the article title. Minimum 3 <h2> sections.\n";
    }

    private function povLabel(string $pov): string
    {
        return match($pov) {
            'first_person'  => 'first person (I/we)',
            'second_person' => 'second person (you)',
            'third_person'  => 'third person (they/it)',
            default         => $pov,
        };
    }

    private function jsonToText(array $data, int $depth = 0): string
    {
        $lines = [];
        $indent = str_repeat('  ', $depth);
        foreach ($data as $key => $value) {
            if (is_array($value)) {
                $lines[] = $indent . "- {$key}:";
                $lines[] = $this->jsonToText($value, $depth + 1);
            } elseif (is_bool($value)) {
                $lines[] = $indent . "- {$key}: " . ($value ? 'yes' : 'no');
            } else {
                $lines[] = $indent . "- {$key}: {$value}";
            }
        }
        return implode("\n", $lines);
    }
}
