<?php
// includes/class-vmo-builder-intelligence.php
if (!defined('ABSPATH')) exit;

/**
 * VMO Builder Intelligence — QA Critic, Competitive Intel Injection, Multi-Agent Enhancement.
 *
 * Hooks into both generation paths:
 *   Path 1 (Chat builder): strategy JSON → QA validate → enhance
 *   Path 2 (Wizard): full HTML → QA validate → refine
 */
class VMO_Builder_Intelligence {

    private static $instance = null;

    public static function get_instance() {
        if (null === self::$instance) self::$instance = new self();
        return self::$instance;
    }

    public function init() {
        // AJAX: JS-side QA critic (called after GrapesJS composition)
        add_action('wp_ajax_vmo_qa_critic_review', [$this, 'ajax_qa_critic']);
        // AJAX: Competitive intel snippet for prompt injection
        add_action('wp_ajax_vmo_get_competitive_context', [$this, 'ajax_competitive_context']);
    }

    /* ═══════════════════════════════════════════
     *  QA CRITIC — Strategy Plan Validation (Path 1)
     * ═══════════════════════════════════════════ */

    /**
     * Validate and enhance a strategy plan JSON before it goes to GrapesJS.
     * Called from generate-content.php after the AI returns the plan.
     *
     * @param array  $plan          The parsed strategy plan.
     * @param array  $profile       Consultation profile data.
     * @param string $business_name Business name.
     * @return array Enhanced plan with QA fixes applied.
     */
    public static function qa_validate_strategy($plan, $profile = [], $business_name = '') {
        if (!is_array($plan) || empty($plan['sections'])) return $plan;

        $issues = [];
        $sections = $plan['sections'];
        $extracted = is_array($profile['extracted_information'] ?? null) ? $profile['extracted_information'] : [];

        // ── Rule 1: Must start with hero ──
        if (!empty($sections[0]) && ($sections[0]['type'] ?? '') !== 'hero') {
            $issues[] = 'first_section_not_hero';
            // Swap: find first hero and move to position 0
            foreach ($sections as $i => $s) {
                if (($s['type'] ?? '') === 'hero' && $i > 0) {
                    $hero = array_splice($sections, $i, 1);
                    array_unshift($sections, $hero[0]);
                    break;
                }
            }
            // If no hero at all, convert first section
            if (($sections[0]['type'] ?? '') !== 'hero') {
                $sections[0]['type'] = 'hero';
            }
        }

        // ── Rule 2: Minimum 5 sections ──
        if (count($sections) < 5) {
            $issues[] = 'too_few_sections';
            $required_types = ['services', 'about', 'testimonials', 'contact', 'cta'];
            $existing_types = array_column($sections, 'type');
            foreach ($required_types as $type) {
                if (count($sections) >= 5) break;
                if (!in_array($type, $existing_types)) {
                    $sections[] = self::generate_placeholder_section($type, $business_name, $extracted);
                }
            }
        }

        // ── Rule 3: Must have a contact section ──
        $has_contact = false;
        foreach ($sections as $s) {
            if (in_array($s['type'] ?? '', ['contact', 'footer'])) { $has_contact = true; break; }
        }
        if (!$has_contact) {
            $issues[] = 'missing_contact';
            $sections[] = self::generate_placeholder_section('contact', $business_name, $extracted);
        }

        // ── Rule 4: Must have proof/trust section in first 3 ──
        $has_early_proof = false;
        for ($i = 0; $i < min(3, count($sections)); $i++) {
            if (in_array($sections[$i]['type'] ?? '', ['proof', 'testimonials', 'stats', 'logos'])) {
                $has_early_proof = true;
                break;
            }
        }
        if (!$has_early_proof) {
            $issues[] = 'no_early_proof';
            $proof_section = self::generate_placeholder_section('proof', $business_name, $extracted);
            array_splice($sections, min(2, count($sections)), 0, [$proof_section]);
        }

        // ── Rule 5: Must have CTA section ──
        $has_cta = false;
        foreach ($sections as $s) {
            if (($s['type'] ?? '') === 'cta') { $has_cta = true; break; }
        }
        if (!$has_cta) {
            $issues[] = 'missing_cta';
            // Insert CTA before last section (contact)
            $cta = self::generate_placeholder_section('cta', $business_name, $extracted);
            $insert_pos = max(0, count($sections) - 1);
            array_splice($sections, $insert_pos, 0, [$cta]);
        }

        // ── Rule 6: Brand consistency ──
        if (isset($plan['brand'])) {
            $brand = &$plan['brand'];
            // Ensure primary/accent colors are valid hex
            if (!empty($brand['primary_color']) && !preg_match('/^#[0-9a-fA-F]{3,8}$/', $brand['primary_color'])) {
                $brand['primary_color'] = '#0f172a';
                $issues[] = 'invalid_primary_color_fixed';
            }
            if (!empty($brand['accent_color']) && !preg_match('/^#[0-9a-fA-F]{3,8}$/', $brand['accent_color'])) {
                $brand['accent_color'] = '#0ea5e9';
                $issues[] = 'invalid_accent_color_fixed';
            }
            // Primary and accent must not be the same
            if (($brand['primary_color'] ?? '') === ($brand['accent_color'] ?? '') && !empty($brand['primary_color'])) {
                $brand['accent_color'] = '#0ea5e9';
                $issues[] = 'identical_colors_fixed';
            }
        }

        // ── Rule 7: Section content quality ──
        foreach ($sections as &$section) {
            // Ensure headline exists and is not generic
            if (empty($section['headline']) || strlen($section['headline']) < 3) {
                $section['headline'] = self::section_default_headline($section['type'] ?? 'section', $business_name);
                $issues[] = 'empty_headline_fixed';
            }
            // Ensure CTA text exists for actionable sections
            $actionable = ['hero', 'cta', 'services', 'pricing', 'showcase'];
            if (in_array($section['type'] ?? '', $actionable) && empty($section['cta_primary'])) {
                $section['cta_primary'] = 'Get Started';
            }
            // Ensure media marker exists
            if (empty($section['media'])) {
                $section['media'] = ($section['type'] ?? '') === 'hero' ? 'video' : 'image';
            }
        }
        unset($section);

        // ── Rule 8: Integrations completeness ──
        if (!isset($plan['integrations'])) $plan['integrations'] = [];
        $defaults = [
            'contact_form' => true,
            'seo_ready' => true,
            'payments_ready' => true,
            'media_replace_ready' => true,
        ];
        foreach ($defaults as $k => $v) {
            if (!isset($plan['integrations'][$k])) $plan['integrations'][$k] = $v;
        }

        $plan['sections'] = $sections;
        $plan['_qa'] = [
            'passed' => empty($issues),
            'issues_fixed' => $issues,
            'critic_version' => '1.0',
            'reviewed_at' => current_time('mysql'),
        ];

        return $plan;
    }

    /* ═══════════════════════════════════════════
     *  QA CRITIC — HTML Validation (Path 2 / JS-side)
     * ═══════════════════════════════════════════ */

    /**
     * AJAX endpoint: JS sends composed HTML for QA review.
     * Returns structured feedback and a quality score.
     */
    public function ajax_qa_critic() {
        check_ajax_referer('vmo_nonce', 'nonce');
        $uid = get_current_user_id();
        if (!$uid) wp_send_json_error('Not logged in');

        $html = wp_unslash($_POST['html'] ?? '');
        if (strlen($html) < 100) wp_send_json_error('HTML too short for review');

        $issues = [];
        $score  = 100;

        // ── Structural checks ──
        if (stripos($html, '<nav') === false && stripos($html, 'navigation') === false) {
            $issues[] = ['severity' => 'warning', 'rule' => 'no_navigation', 'message' => 'No navigation/menu element detected'];
            $score -= 5;
        }
        if (stripos($html, '<footer') === false) {
            $issues[] = ['severity' => 'warning', 'rule' => 'no_footer', 'message' => 'No footer element detected'];
            $score -= 5;
        }
        if (stripos($html, '<h1') === false) {
            $issues[] = ['severity' => 'error', 'rule' => 'no_h1', 'message' => 'No H1 heading found — bad for SEO'];
            $score -= 10;
        }

        // ── Accessibility ──
        $img_count = preg_match_all('/<img\b/i', $html);
        $alt_count = preg_match_all('/<img\b[^>]*\balt\s*=/i', $html);
        if ($img_count > 0 && $alt_count < $img_count) {
            $missing = $img_count - $alt_count;
            $issues[] = ['severity' => 'warning', 'rule' => 'missing_alt', 'message' => "$missing image(s) missing alt attributes"];
            $score -= min(10, $missing * 2);
        }

        // ── SEO ──
        if (stripos($html, '<meta name="description"') === false && stripos($html, 'meta-description') === false) {
            $issues[] = ['severity' => 'info', 'rule' => 'no_meta_desc', 'message' => 'Consider adding a meta description for SEO'];
            $score -= 3;
        }

        // ── CTA presence ──
        $cta_patterns = ['get started', 'contact us', 'book now', 'sign up', 'learn more', 'buy now', 'schedule', 'call now', 'request', 'shop now'];
        $has_cta = false;
        $html_lower = strtolower($html);
        foreach ($cta_patterns as $pattern) {
            if (strpos($html_lower, $pattern) !== false) { $has_cta = true; break; }
        }
        if (!$has_cta) {
            $issues[] = ['severity' => 'warning', 'rule' => 'no_cta', 'message' => 'No clear call-to-action found'];
            $score -= 8;
        }

        // ── Contact info ──
        $has_phone = (bool) preg_match('/[\+]?[1-9]\d{6,14}/', $html);
        $has_email_link = stripos($html, 'mailto:') !== false;
        $has_form = stripos($html, '<form') !== false || stripos($html, 'contact-form') !== false;
        if (!$has_phone && !$has_email_link && !$has_form) {
            $issues[] = ['severity' => 'warning', 'rule' => 'no_contact', 'message' => 'No contact information (phone, email, or form) detected'];
            $score -= 5;
        }

        // ── Content volume ──
        $text_only = wp_strip_all_tags($html);
        $word_count = str_word_count($text_only);
        if ($word_count < 150) {
            $issues[] = ['severity' => 'warning', 'rule' => 'thin_content', 'message' => "Only $word_count words — may feel sparse"];
            $score -= 8;
        }

        // ── Section count ──
        $section_count = preg_match_all('/<section\b/i', $html);
        if ($section_count < 3) {
            $issues[] = ['severity' => 'info', 'rule' => 'few_sections', 'message' => "Only $section_count section(s) detected — consider adding more"];
            $score -= 3;
        }

        // ── Mobile readiness ──
        if (stripos($html, 'viewport') === false && stripos($html, 'responsive') === false && stripos($html, 'max-width') === false) {
            $issues[] = ['severity' => 'warning', 'rule' => 'no_responsive', 'message' => 'No responsive/viewport indicators found'];
            $score -= 5;
        }

        $score = max(0, min(100, $score));
        $grade = $score >= 90 ? 'A' : ($score >= 75 ? 'B' : ($score >= 60 ? 'C' : ($score >= 40 ? 'D' : 'F')));

        wp_send_json_success([
            'score'  => $score,
            'grade'  => $grade,
            'issues' => $issues,
            'passed' => ($score >= 70),
            'summary' => count($issues) === 0 ? 'Excellent! No issues found.' : count($issues) . ' issue(s) detected.',
        ]);
    }

    /* ═══════════════════════════════════════════
     *  COMPETITIVE INTELLIGENCE — Prompt Injection
     * ═══════════════════════════════════════════ */

    /**
     * Build a competitive intelligence snippet for injection into generation prompts.
     *
     * @param int $user_id
     * @return string  A formatted text block for system message injection.
     */
    public static function get_competitive_context($user_id) {
        $context_parts = [];

        // 1. Deep research insights (already cached from consultation)
        if (function_exists('vmo_get_cached_industry_insights')) {
            $insights = vmo_get_cached_industry_insights($user_id);
            if (!empty($insights)) {
                $top_competitors = [];
                if (!empty($insights['competitors'])) {
                    foreach (array_slice((array) $insights['competitors'], 0, 3) as $comp) {
                        $name = is_array($comp) ? ($comp['name'] ?? $comp['domain'] ?? '') : (string) $comp;
                        if ($name) $top_competitors[] = $name;
                    }
                }
                if (!empty($top_competitors)) {
                    $context_parts[] = "TOP COMPETITORS: " . implode(', ', $top_competitors);
                }
                if (!empty($insights['market_trends'])) {
                    $trends = is_array($insights['market_trends']) ? implode('; ', array_slice($insights['market_trends'], 0, 3)) : substr((string) $insights['market_trends'], 0, 300);
                    $context_parts[] = "MARKET TRENDS: " . $trends;
                }
                if (!empty($insights['differentiators'])) {
                    $diff = is_array($insights['differentiators']) ? implode('; ', array_slice($insights['differentiators'], 0, 3)) : substr((string) $insights['differentiators'], 0, 300);
                    $context_parts[] = "COMPETITIVE ADVANTAGES: " . $diff;
                }
            }
        }

        // 2. Industry-specific design intelligence
        $profile = [];
        if (function_exists('vmo_get_consultation_profile')) {
            $profile = vmo_get_consultation_profile($user_id);
        }
        $extracted = is_array($profile['extracted_information'] ?? null) ? $profile['extracted_information'] : [];
        $industry = '';
        foreach (['industry', 'business_type', 'businessType', 'niche', 'category'] as $k) {
            if (!empty($extracted[$k])) { $industry = sanitize_text_field((string) $extracted[$k]); break; }
        }

        if ($industry) {
            $design_guidance = self::get_industry_design_guidance($industry);
            if ($design_guidance) {
                $context_parts[] = "INDUSTRY DESIGN INTELLIGENCE ($industry): $design_guidance";
            }
        }

        // 3. Target audience preferences
        $target_audience = '';
        foreach (['target_audience', 'targetAudience', 'ideal_customer', 'audience'] as $k) {
            if (!empty($extracted[$k])) {
                $target_audience = is_array($extracted[$k]) ? implode(', ', $extracted[$k]) : sanitize_text_field((string) $extracted[$k]);
                break;
            }
        }
        if ($target_audience) {
            $context_parts[] = "TARGET AUDIENCE: $target_audience — Design choices, imagery, and copy tone must resonate with this audience.";
        }

        // 4. USP/value props for differentiation
        $usps = [];
        foreach (['unique_selling_points', 'usp', 'value_propositions', 'valuePropositions', 'strengths'] as $k) {
            if (!empty($extracted[$k])) {
                $usps = is_array($extracted[$k]) ? $extracted[$k] : [$extracted[$k]];
                break;
            }
        }
        if (!empty($usps)) {
            $context_parts[] = "UNIQUE SELLING POINTS (must be prominent): " . implode('; ', array_slice($usps, 0, 5));
        }

        if (empty($context_parts)) return '';

        return "COMPETITIVE INTELLIGENCE & MARKET POSITIONING:\n" . implode("\n", $context_parts)
            . "\n\nUSE THIS INTELLIGENCE: Position the website to outperform competitors. Highlight USPs prominently. Match design patterns that work in this industry while standing out visually.";
    }

    /**
     * AJAX: Return competitive context for JS-side prompt enrichment.
     */
    public function ajax_competitive_context() {
        check_ajax_referer('vmo_nonce', 'nonce');
        $uid = get_current_user_id();
        if (!$uid) wp_send_json_error('Not logged in');

        $context = self::get_competitive_context($uid);
        wp_send_json_success(['context' => $context]);
    }

    /* ═══════════════════════════════════════════
     *  INDUSTRY DESIGN GUIDANCE
     * ═══════════════════════════════════════════ */

    private static function get_industry_design_guidance($industry) {
        $industry_lower = strtolower($industry);
        $map = [
            'restaurant'  => 'Use warm, inviting imagery. Menu should be scannable. Reservation CTA above fold. Food photography is critical. Mobile-first for on-the-go browsing.',
            'law'         => 'Project authority and trust. Dark, sophisticated palette. Testimonials and case results prominent. Clear practice area navigation. Professional headshots essential.',
            'real estate' => 'Property search/gallery is hero experience. High-res property photos. Map integration implied. Agent profiles with contact CTAs. Neighborhood guides build authority.',
            'healthcare'  => 'Clean, calming design. Trust badges and certifications visible. Easy appointment booking. Patient testimonials. HIPAA compliance notice in footer. Accessible design critical.',
            'ecommerce'   => 'Product-first hero. Fast category navigation. Trust signals (reviews, security badges) early. Cart-prominent header. Urgency elements for conversions.',
            'saas'        => 'Product demo/screenshot as hero. Feature comparison grid. Pricing transparency. Free trial CTA. Integration logos. Customer count social proof.',
            'fitness'     => 'High-energy imagery and bold typography. Class schedule visible. Membership pricing clear. Trainer profiles. Transformation testimonials with before/after.',
            'beauty'      => 'Elegant, lifestyle-driven imagery. Service menu with pricing. Online booking prominent. Portfolio/gallery of work. Instagram feed integration.',
            'education'   => 'Clear course catalog. Student outcomes/success stories. Faculty credentials. Enrollment CTA. Program comparison. Accreditation badges.',
            'construction'=> 'Project portfolio with before/after. Service area map. License/insurance badges. Free estimate CTA. Safety credentials. Heavy equipment imagery.',
            'finance'     => 'Trust and security paramount. Calculator tools. Certification badges. Clean data visualization. Compliance notices. Professional team photos.',
            'photography' => 'Full-bleed portfolio gallery is the product. Minimal UI — let images speak. Booking/inquiry CTA. Session type packages. Client testimonials with photos.',
            'consulting'  => 'Thought leadership content. Case studies with results. Client logos. Methodology visualization. Calendar booking integration. Industry expertise badges.',
            'tech'        => 'Modern, cutting-edge design. Product demos/screenshots. API documentation link. Integration ecosystem. Developer-friendly. Performance metrics.',
            'nonprofit'   => 'Mission-driven storytelling. Impact metrics prominent. Donation CTA above fold. Volunteer signup. Event calendar. Transparency/annual report links.',
        ];

        foreach ($map as $key => $guidance) {
            if (strpos($industry_lower, $key) !== false) return $guidance;
        }
        return '';
    }

    /* ═══════════════════════════════════════════
     *  SECTION GENERATORS (for QA gap-filling)
     * ═══════════════════════════════════════════ */

    private static function generate_placeholder_section($type, $business_name, $extracted) {
        $phone = '';
        foreach (['business_phone', 'phone', 'supportPhone'] as $k) {
            if (!empty($extracted[$k])) { $phone = $extracted[$k]; break; }
        }
        $email = '';
        foreach (['business_email', 'businessEmail', 'email'] as $k) {
            if (!empty($extracted[$k])) { $email = sanitize_email($extracted[$k]); break; }
        }

        $templates = [
            'proof' => [
                'type' => 'proof',
                'headline' => 'Trusted by Businesses Like Yours',
                'subheadline' => 'Join hundreds of satisfied clients',
                'body' => 'Our track record speaks for itself.',
                'cta_primary' => '',
                'media' => 'image',
                'bullets' => ['100+ Happy Clients', '5-Star Average Rating', 'Industry Certified'],
                'design_direction' => 'logo bar with stats counters',
                'interaction_style' => 'count-up animation on scroll',
            ],
            'services' => [
                'type' => 'services',
                'headline' => 'What We Offer',
                'subheadline' => "Comprehensive solutions from $business_name",
                'body' => 'Our services are designed to deliver real results.',
                'cta_primary' => 'Learn More',
                'media' => 'image',
                'bullets' => [],
                'design_direction' => 'card grid with icons',
                'interaction_style' => 'staggered reveal on scroll',
            ],
            'about' => [
                'type' => 'about',
                'headline' => "About $business_name",
                'subheadline' => 'Our story and mission',
                'body' => "At $business_name, we are committed to excellence and delivering exceptional value.",
                'cta_primary' => 'Meet the Team',
                'media' => 'image',
                'bullets' => [],
                'design_direction' => 'split layout with team photo',
                'interaction_style' => 'parallax background',
            ],
            'testimonials' => [
                'type' => 'testimonials',
                'headline' => 'What Our Clients Say',
                'subheadline' => 'Real results from real people',
                'body' => '',
                'cta_primary' => '',
                'media' => 'image',
                'bullets' => [],
                'design_direction' => 'carousel with star ratings',
                'interaction_style' => 'auto-scroll carousel',
            ],
            'contact' => [
                'type' => 'contact',
                'headline' => 'Get in Touch',
                'subheadline' => "Ready to work with $business_name?",
                'body' => "Reach out today and let's discuss how we can help." . ($phone ? " Call us at $phone." : '') . ($email ? " Email: $email" : ''),
                'cta_primary' => 'Send Message',
                'media' => 'none',
                'bullets' => [],
                'design_direction' => 'contact form with map',
                'interaction_style' => 'form with floating labels',
            ],
            'cta' => [
                'type' => 'cta',
                'headline' => 'Ready to Get Started?',
                'subheadline' => "Take the next step with $business_name",
                'body' => "Don't wait — get in touch today and see the difference.",
                'cta_primary' => 'Get Started Now',
                'cta_secondary' => 'Learn More',
                'media' => 'image',
                'bullets' => [],
                'design_direction' => 'full-width gradient banner',
                'interaction_style' => 'hover glow on CTA button',
            ],
        ];

        return $templates[$type] ?? [
            'type' => $type,
            'headline' => ucfirst($type),
            'subheadline' => '',
            'body' => '',
            'cta_primary' => '',
            'media' => 'image',
            'bullets' => [],
        ];
    }

    private static function section_default_headline($type, $business_name) {
        $map = [
            'hero' => "Welcome to $business_name",
            'services' => 'Our Services',
            'about' => "About $business_name",
            'contact' => 'Get in Touch',
            'testimonials' => 'What Our Clients Say',
            'cta' => 'Ready to Get Started?',
            'proof' => 'Why Choose Us',
            'pricing' => 'Our Pricing',
            'faq' => 'Frequently Asked Questions',
            'gallery' => 'Our Work',
            'showcase' => 'Featured Projects',
            'products' => 'Our Products',
        ];
        return $map[$type] ?? ucfirst(str_replace('_', ' ', $type));
    }
}
