<?php
/**
 * VMO GrapesJS Server-Side Composer
 *
 * Mirrors the client-side vmo-grapes-adapter.js composition engine.
 * Used by the 12-chunk pipeline and other server-side generation paths
 * to produce premium React/Tailwind/GSAP website output.
 *
 * @since 9.1.0
 */
if (!defined('ABSPATH')) exit;

class VMO_Grapes_Composer {

    /* ────────────────── CDN CONFIGURATION ────────────────── */

    const CDN = [
        'font'        => 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap',
        'tailwind'    => 'https://cdn.tailwindcss.com',
        'react'       => 'https://unpkg.com/react@18/umd/react.production.min.js',
        'react_dom'   => 'https://unpkg.com/react-dom@18/umd/react-dom.production.min.js',
        'gsap'        => 'https://unpkg.com/gsap@3.12.5/dist/gsap.min.js',
        'scrolltrigger' => 'https://unpkg.com/gsap@3.12.5/dist/ScrollTrigger.min.js',
        'lenis'       => 'https://unpkg.com/lenis@1.1.13/dist/lenis.min.js',
        'swiper_css'  => 'https://unpkg.com/swiper@11/swiper-bundle.min.css',
        'swiper_js'   => 'https://unpkg.com/swiper@11/swiper-bundle.min.js',
        'lottie'      => 'https://unpkg.com/lottie-web@5.12.2/build/player/lottie.min.js',
        'aos_css'     => 'https://unpkg.com/aos@2.3.4/dist/aos.css',
        'aos_js'      => 'https://unpkg.com/aos@2.3.4/dist/aos.js',
    ];

    /* ────────────────── PUBLIC API ────────────────── */

    /**
     * Wrap existing HTML in the premium React/Tailwind/GSAP shell.
     * Used by the 12-chunk pipeline to upgrade raw AI-generated HTML.
     *
     * @param string $html  Raw page HTML from AI generation.
     * @param array  $meta  Optional metadata: primary_color, accent_color, tech_stack, business_name.
     * @return string Full HTML with CDN references, base styles, and initialization scripts.
     */
    public static function wrap_in_premium_shell($html, $meta = []) {
        $html = self::sanitize_output_html($html);
        $primary = esc_attr($meta['primary_color'] ?? '#0f172a');
        $accent  = esc_attr($meta['accent_color']  ?? '#0ea5e9');
        $biz     = esc_attr($meta['business_name']  ?? '');
        $tech    = is_array($meta['tech_stack'] ?? null) ? $meta['tech_stack'] : ['React 18', 'Tailwind CSS', 'GSAP'];

        $cdn_head     = self::build_cdn_head($tech, $primary, $accent);
        $base_css     = self::build_base_css($primary, $accent);
        $init_scripts = self::build_init_scripts();

        return $cdn_head
            . "\n<style data-vmo-premium=\"base\">" . $base_css . "</style>\n"
            . '<div id="vmo-gjs-page" class="vmo-gjs-page font-[Inter,system-ui,sans-serif]" '
            . 'data-vmo-generated="grapesjs-shell" data-business="' . $biz . '">' . "\n"
            . $html . "\n"
            . "</div>\n"
            . $init_scripts;
    }

    /**
     * Compose a full page from a strategy JSON plan (mirrors JS adapter composeWebsite).
     *
     * @param array $plan    Strategy plan with site, brand, tech_stack, integrations, sections.
     * @param array $context Optional: phone_number, email_address.
     * @return string Full premium HTML.
     */
    public static function compose_from_strategy($plan, $context = []) {
        if (!is_array($plan)) $plan = [];

        $site         = is_array($plan['site'] ?? null) ? $plan['site'] : [];
        $brand        = is_array($plan['brand'] ?? null) ? $plan['brand'] : [];
        $integrations = is_array($plan['integrations'] ?? null) ? $plan['integrations'] : [];
        $sections     = is_array($plan['sections'] ?? null) ? $plan['sections'] : [];
        $tech         = is_array(($plan['tech_stack'] ?? [])['selected'] ?? null) ? $plan['tech_stack']['selected'] : ['React 18', 'Tailwind CSS', 'GSAP'];

        // Merge contact info from context
        if (!empty($context['phone_number']) && empty($integrations['phone_number'])) {
            $integrations['phone_number'] = $context['phone_number'];
            $integrations['phone_enabled'] = true;
        }
        if (!empty($context['email_address']) && empty($integrations['email_address'])) {
            $integrations['email_address'] = $context['email_address'];
            $integrations['email_enabled'] = true;
        }

        $biz     = esc_html($site['business_name'] ?? 'Business Website');
        $tagline = esc_html($site['tagline'] ?? '');
        $goal    = esc_html($site['goal'] ?? '');
        $primary = $brand['primary_color'] ?? '#0f172a';
        $accent  = $brand['accent_color']  ?? '#0ea5e9';

        $total = count($sections);
        $sections_html = '';
        foreach ($sections as $i => $section) {
            $sections_html .= self::render_section($section, $i, $total, $integrations);
        }

        $header = self::render_header($biz, $tagline, $tech);
        $footer = self::render_footer($biz, $goal);

        return self::wrap_in_premium_shell(
            $header . $sections_html . $footer,
            ['primary_color' => $primary, 'accent_color' => $accent, 'tech_stack' => $tech, 'business_name' => $biz]
        );
    }

    private static function sanitize_output_html($html) {
        $html = (string) $html;
        if ($html === '') {
            return '';
        }

        $html = preg_replace('/<!--.*?-->/s', '', $html);
        $html = preg_replace('/AI\s+Image\s+Generating\.\.\./i', '', $html);
        $html = preg_replace('/AI\s+Video\s+Generating\.\.\./i', '', $html);
        $html = preg_replace('/A professional (image|video) will appear here/i', '', $html);

        return is_string($html) ? $html : '';
    }

    /* ────────────────── HEADER / FOOTER ────────────────── */

    private static function render_header($biz, $tagline, $tech) {
        $chips = '';
        foreach (array_slice($tech, 0, 5) as $t) {
            $te = esc_html($t);
            $chips .= '<span class="px-3 py-1 text-[11px] font-semibold rounded-full bg-indigo-50 text-indigo-700 border border-indigo-100">' . $te . '</span>';
        }
        return '<header class="sticky top-0 z-50 bg-white/80 backdrop-blur-xl border-b border-gray-100/60">'
            . '<div class="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between">'
            . '<div><h1 class="text-xl font-bold text-gray-900 tracking-tight">' . $biz . '</h1>'
            . ($tagline ? '<p class="text-sm text-gray-500 mt-0.5">' . $tagline . '</p>' : '')
            . '</div>'
            . '<nav class="hidden md:flex items-center gap-6 text-sm font-medium text-gray-600">'
            . '<a href="#section-1" class="hover:text-gray-900 transition">Home</a>'
            . '<a href="#section-footer" class="hover:text-gray-900 transition">Contact</a>'
            . '</nav>'
            . '<div class="hidden lg:flex flex-wrap gap-1.5">' . $chips . '</div>'
            . '</div></header>' . "\n";
    }

    private static function render_footer($biz, $goal) {
        $year = date('Y');
        return '<footer id="section-footer" class="bg-gray-950 text-gray-400 py-16">'
            . '<div class="max-w-7xl mx-auto px-6 flex flex-col md:flex-row justify-between gap-8">'
            . '<div><p class="text-white font-semibold text-lg">' . $biz . '</p>'
            . '<p class="mt-2 text-sm max-w-md">' . ($goal ?: 'Built to convert and scale.') . '</p></div>'
            . '<div class="text-sm"><p>&copy; ' . $year . ' ' . $biz . '. All rights reserved.</p>'
            . '<p class="mt-1">Powered by VMO AI</p></div>'
            . '</div></footer>' . "\n";
    }

    /* ────────────────── SECTION DISPATCHER ────────────────── */

    private static function render_section($section, $index, $total, $integrations) {
        if (!is_array($section)) $section = [];
        $type = sanitize_key($section['type'] ?? 'section');

        switch ($type) {
            case 'hero':         return self::section_hero($section, $index);
            case 'services':
            case 'features':     return self::section_services($section, $index);
            case 'about':        return self::section_about($section, $index);
            case 'testimonials':
            case 'reviews':      return self::section_testimonials($section, $index);
            case 'products':
            case 'shop':
            case 'ecommerce':    return self::section_products($section, $index);
            case 'pricing':      return self::section_pricing($section, $index);
            case 'contact':      return self::section_contact($section, $index, $integrations);
            case 'gallery':
            case 'portfolio':    return self::section_gallery($section, $index);
            case 'team':         return self::section_team($section, $index);
            case 'faq':          return self::section_faq($section, $index);
            case 'cta':          return self::section_cta($section, $index);
            default:             return self::section_default($section, $index);
        }
    }

    /* ────────────────── MEDIA HELPER ────────────────── */

    private static function media_placeholder($type_hint, $media_type = 'image', $index = 0) {
        $id = 'gjs-media-' . $index . '-' . wp_rand(1000, 9999);
        $seed = urlencode($type_hint . '-' . $index);
        
        // ✅ Generate AI media prompt based on the type hint for post-render generation
        $ai_prompt = 'Professional, high-quality ' . $type_hint . ' image for a modern business website, photorealistic, cinematic lighting, premium feel';
        
        if ($media_type === 'video') {
            $video_prompt = 'Cinematic ' . $type_hint . ' video, smooth camera movement, professional lighting, modern business atmosphere, 4K quality';
            return '<div class="relative group">'
                . '<div class="vmo-media-placeholder w-full min-h-[280px] rounded-2xl flex items-center justify-center" '
                . 'data-media-id="' . $id . '" data-type="video" '
                . 'data-vmo-sora="true" data-vmo-sora-prompt="' . esc_attr($video_prompt) . '" '
                . 'style="background:linear-gradient(135deg,#0f172a,#1e293b);position:relative;color:transparent;font-size:0;line-height:0;"></div>'
                . self::replace_button_overlay($id) . '</div>';
        }
        
        // ✅ Use a gradient placeholder with AI generation marker instead of picsum.photos
        return '<div class="relative group">'
            . '<div class="vmo-media-placeholder w-full min-h-[280px] rounded-2xl flex items-center justify-center" '
            . 'data-media-id="' . $id . '" data-type="image" '
            . 'data-vmo-generate="true" data-vmo-prompt="' . esc_attr($ai_prompt) . '" '
            . 'style="background:linear-gradient(135deg,#1e293b,#334155);position:relative;color:transparent;font-size:0;line-height:0;"></div>'
            . self::replace_button_overlay($id) . '</div>';
    }

    private static function replace_button_overlay($media_id) {
        return '<button class="vmo-replace-btn absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/40 '
            . 'opacity-0 group-hover:opacity-100 transition-all duration-300 rounded-2xl cursor-pointer" '
            . 'data-replace-media="' . esc_attr($media_id) . '" title="Replace media">'
            . '<span class="px-4 py-2 bg-white/90 backdrop-blur-sm text-gray-900 text-sm font-semibold rounded-lg shadow-lg">'
            . '&#x1F504; Replace</span></button>';
    }

    /* ────────────────── SECTION RENDERERS ────────────────── */

    private static function section_hero($s, $i) {
        $id = 'section-' . ($i + 1) . '-hero';
        $hl = esc_html($s['headline'] ?? 'Welcome');
        $sub = esc_html($s['subheadline'] ?? '');
        $body = esc_html($s['body'] ?? '');
        $cta1 = esc_html($s['cta_primary'] ?? '');
        $cta2 = esc_html($s['cta_secondary'] ?? '');
        $media = self::media_placeholder('hero', ($s['media'] ?? 'image'), $i);

        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="relative min-h-[85vh] flex items-center overflow-hidden bg-gray-950" data-vmo-section-type="hero" data-vmo-animate>'
            . '<div class="absolute inset-0 z-0">' . $media
            . '<div class="absolute inset-0 bg-gradient-to-r from-gray-950/80 via-gray-950/50 to-transparent"></div></div>'
            . '<div class="relative z-10 max-w-7xl mx-auto px-6 py-28 lg:py-36">'
            . '<h2 class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-extrabold text-white leading-[1.08] tracking-tight max-w-4xl">' . $hl . '</h2>'
            . ($sub ? '<p class="mt-5 text-xl md:text-2xl text-white/80 font-medium max-w-2xl">' . $sub . '</p>' : '')
            . ($body ? '<p class="mt-4 text-lg text-white/60 max-w-xl leading-relaxed">' . $body . '</p>' : '')
            . '<div class="mt-10 flex flex-wrap gap-4">'
            . ($cta1 ? '<a href="#" class="inline-flex items-center px-8 py-4 bg-accent text-white font-semibold rounded-xl shadow-lg shadow-accent/25 hover:shadow-xl hover:-translate-y-0.5 transition-all duration-300">' . $cta1 . '</a>' : '')
            . ($cta2 ? '<a href="#" class="inline-flex items-center px-8 py-4 bg-white/10 backdrop-blur-sm text-white font-semibold rounded-xl border border-white/20 hover:bg-white/20 transition-all duration-300">' . $cta2 . '</a>' : '')
            . '</div></div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_services($s, $i) {
        $id = 'section-' . ($i + 1) . '-services';
        $hl = esc_html($s['headline'] ?? 'Our Services');
        $sub = esc_html($s['subheadline'] ?? '');
        $body = esc_html($s['body'] ?? '');
        $bullets = is_array($s['bullets'] ?? null) ? $s['bullets'] : [];
        $cards = '';
        $icons = ['&#x1F680;', '&#x2B50;', '&#x1F4A1;', '&#x1F3AF;', '&#x26A1;', '&#x1F527;'];
        foreach ($bullets as $bi => $item) {
            $icon = $icons[$bi % count($icons)];
            $cards .= '<div class="group p-8 bg-white rounded-2xl border border-gray-100 hover:border-accent/30 shadow-sm hover:shadow-xl hover:-translate-y-1 transition-all duration-300">'
                . '<div class="w-12 h-12 flex items-center justify-center rounded-xl bg-accent/10 text-2xl mb-5">' . $icon . '</div>'
                . '<h3 class="text-lg font-bold text-gray-900">' . esc_html($item) . '</h3>'
                . '</div>';
        }
        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 bg-gray-50/50" data-vmo-section-type="services" data-vmo-animate>'
            . '<div class="max-w-7xl mx-auto px-6">'
            . '<div class="text-center max-w-3xl mx-auto mb-16">'
            . ($sub ? '<p class="text-accent font-semibold tracking-wide uppercase text-sm mb-3">' . $sub . '</p>' : '')
            . '<h2 class="text-3xl md:text-5xl font-bold text-gray-900 tracking-tight">' . $hl . '</h2>'
            . ($body ? '<p class="mt-5 text-lg text-gray-600 leading-relaxed">' . $body . '</p>' : '')
            . '</div>'
            . '<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">' . $cards . '</div>'
            . '</div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_about($s, $i) {
        $id = 'section-' . ($i + 1) . '-about';
        $hl = esc_html($s['headline'] ?? 'About Us');
        $sub = esc_html($s['subheadline'] ?? '');
        $body = esc_html($s['body'] ?? '');
        $media = self::media_placeholder('about', ($s['media'] ?? 'image'), $i);
        $swap = ($i % 2 === 1);
        $order = $swap ? 'md:order-last' : '';

        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 bg-white" data-vmo-section-type="about" data-vmo-animate>'
            . '<div class="max-w-7xl mx-auto px-6 grid grid-cols-1 md:grid-cols-2 gap-12 lg:gap-20 items-center">'
            . '<div class="' . $order . '">'
            . ($sub ? '<p class="text-accent font-semibold tracking-wide uppercase text-sm mb-3">' . $sub . '</p>' : '')
            . '<h2 class="text-3xl md:text-5xl font-bold text-gray-900 tracking-tight leading-tight">' . $hl . '</h2>'
            . ($body ? '<p class="mt-5 text-lg text-gray-600 leading-relaxed">' . $body . '</p>' : '')
            . '</div><div>' . $media . '</div>'
            . '</div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_testimonials($s, $i) {
        $id = 'section-' . ($i + 1) . '-testimonials';
        $hl = esc_html($s['headline'] ?? 'What Our Clients Say');
        $sub = esc_html($s['subheadline'] ?? '');
        $bullets = is_array($s['bullets'] ?? null) ? $s['bullets'] : ['Great service and results!', 'Absolutely transformed our business.', 'Highly recommend to anyone.'];
        $slides = '';
        foreach ($bullets as $bi => $quote) {
            $slides .= '<div class="swiper-slide"><div class="p-8 bg-white rounded-2xl border border-gray-100 shadow-sm">'
                . '<p class="text-gray-700 text-lg leading-relaxed italic">&ldquo;' . esc_html($quote) . '&rdquo;</p>'
                . '<p class="mt-4 text-sm font-semibold text-gray-900">Client ' . ($bi + 1) . '</p>'
                . '</div></div>';
        }
        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 bg-gray-50/50" data-vmo-section-type="testimonials" data-vmo-animate>'
            . '<div class="max-w-7xl mx-auto px-6">'
            . '<div class="text-center max-w-3xl mx-auto mb-16">'
            . ($sub ? '<p class="text-accent font-semibold tracking-wide uppercase text-sm mb-3">' . $sub . '</p>' : '')
            . '<h2 class="text-3xl md:text-5xl font-bold text-gray-900 tracking-tight">' . $hl . '</h2>'
            . '</div>'
            . '<div class="swiper vmo-testimonial-swiper"><div class="swiper-wrapper">' . $slides . '</div>'
            . '<div class="swiper-pagination mt-8"></div></div>'
            . '</div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_products($s, $i) {
        $id = 'section-' . ($i + 1) . '-products';
        $hl = esc_html($s['headline'] ?? 'Our Products');
        $sub = esc_html($s['subheadline'] ?? '');
        $bullets = is_array($s['bullets'] ?? null) ? $s['bullets'] : ['Product A', 'Product B', 'Product C'];
        $cards = '';
        foreach ($bullets as $pi => $product) {
            $media_id = 'product-media-' . $i . '-' . $pi . '-' . wp_rand(1000, 9999);
            $seed = urlencode('product-' . $pi);
            $cards .= '<div class="bg-white rounded-2xl border border-gray-100 overflow-hidden shadow-sm hover:shadow-xl hover:-translate-y-1 transition-all duration-300 group">'
                . '<div class="relative aspect-[4/3] overflow-hidden">'
                . '<img class="vmo-media-placeholder w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" '
                . 'data-media-id="' . $media_id . '" data-type="image" loading="lazy" '
                . 'src="https://picsum.photos/seed/' . $seed . '/800/600" alt="' . esc_attr($product) . '" />'
                . self::replace_button_overlay($media_id)
                . '</div>'
                . '<div class="p-6"><h3 class="text-lg font-bold text-gray-900">' . esc_html($product) . '</h3>'
                . '<p class="mt-2 text-gray-600 text-sm">Premium quality product</p>'
                . '<div class="mt-4 flex items-center justify-between">'
                . '<span class="text-2xl font-bold text-gray-900">$99</span>'
                . '<button class="vmo-pay-btn px-6 py-2.5 bg-accent text-white font-semibold rounded-xl hover:shadow-lg transition-all duration-300" '
                . 'data-vmo-product="' . esc_attr($product) . '">Buy Now</button>'
                . '</div></div></div>';
        }
        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 bg-white" data-vmo-section-type="products" data-vmo-animate>'
            . '<div class="max-w-7xl mx-auto px-6">'
            . '<div class="text-center max-w-3xl mx-auto mb-16">'
            . ($sub ? '<p class="text-accent font-semibold tracking-wide uppercase text-sm mb-3">' . $sub . '</p>' : '')
            . '<h2 class="text-3xl md:text-5xl font-bold text-gray-900 tracking-tight">' . $hl . '</h2>'
            . '</div>'
            . '<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">' . $cards . '</div>'
            . '</div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_pricing($s, $i) {
        $id = 'section-' . ($i + 1) . '-pricing';
        $hl = esc_html($s['headline'] ?? 'Pricing');
        $sub = esc_html($s['subheadline'] ?? '');
        $bullets = is_array($s['bullets'] ?? null) ? $s['bullets'] : ['Starter — $29/mo', 'Pro — $79/mo', 'Enterprise — $199/mo'];
        $cards = '';
        $featured_index = (int) floor(count($bullets) / 2);
        foreach ($bullets as $pi => $plan_label) {
            $is_featured = ($pi === $featured_index);
            $ring = $is_featured ? 'ring-2 ring-accent scale-105' : '';
            $badge = $is_featured ? '<span class="absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 bg-accent text-white text-xs font-bold rounded-full">Popular</span>' : '';
            $cards .= '<div class="relative p-8 bg-white rounded-2xl border border-gray-100 shadow-sm ' . $ring . '">'
                . $badge
                . '<h3 class="text-xl font-bold text-gray-900">' . esc_html($plan_label) . '</h3>'
                . '<a href="#" class="mt-6 block w-full text-center px-6 py-3 bg-accent text-white font-semibold rounded-xl hover:shadow-lg transition-all duration-300">Get Started</a>'
                . '</div>';
        }
        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 bg-gray-50/50" data-vmo-section-type="pricing" data-vmo-animate>'
            . '<div class="max-w-7xl mx-auto px-6">'
            . '<div class="text-center max-w-3xl mx-auto mb-16">'
            . ($sub ? '<p class="text-accent font-semibold tracking-wide uppercase text-sm mb-3">' . $sub . '</p>' : '')
            . '<h2 class="text-3xl md:text-5xl font-bold text-gray-900 tracking-tight">' . $hl . '</h2>'
            . '</div>'
            . '<div class="grid grid-cols-1 md:grid-cols-3 gap-8 items-start">' . $cards . '</div>'
            . '</div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_contact($s, $i, $integrations) {
        $id = 'section-' . ($i + 1) . '-contact';
        $hl = esc_html($s['headline'] ?? 'Get In Touch');
        $sub = esc_html($s['subheadline'] ?? '');
        $body = esc_html($s['body'] ?? '');

        $chips = '';
        if (!empty($integrations['phone_enabled']) && !empty($integrations['phone_number'])) {
            $phone = esc_html($integrations['phone_number']);
            $href  = 'tel:' . preg_replace('/[^+\d]/', '', $integrations['phone_number']);
            $chips .= '<a href="' . esc_attr($href) . '" class="flex items-center gap-3 px-5 py-3 rounded-xl bg-accent/10 text-accent font-semibold hover:bg-accent/20 transition">&#x1F4DE; ' . $phone . '</a>';
        }
        if (!empty($integrations['email_enabled']) && !empty($integrations['email_address'])) {
            $email = esc_html($integrations['email_address']);
            $chips .= '<a href="mailto:' . esc_attr($integrations['email_address']) . '" class="flex items-center gap-3 px-5 py-3 rounded-xl bg-accent/10 text-accent font-semibold hover:bg-accent/20 transition">&#x2709; ' . $email . '</a>';
        }

        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 bg-white" data-vmo-section-type="contact" data-vmo-animate>'
            . '<div class="max-w-7xl mx-auto px-6 grid grid-cols-1 md:grid-cols-2 gap-16">'
            . '<div>'
            . ($sub ? '<p class="text-accent font-semibold tracking-wide uppercase text-sm mb-3">' . $sub . '</p>' : '')
            . '<h2 class="text-3xl md:text-5xl font-bold text-gray-900 tracking-tight">' . $hl . '</h2>'
            . ($body ? '<p class="mt-5 text-lg text-gray-600 leading-relaxed">' . $body . '</p>' : '')
            . ($chips ? '<div class="mt-8 flex flex-col sm:flex-row gap-4">' . $chips . '</div>' : '')
            . '</div>'
            . '<form class="space-y-5" data-vmo-form="lead" onsubmit="event.preventDefault();">'
            . '<input type="text" name="name" placeholder="Your name" required class="w-full px-5 py-3.5 rounded-xl border border-gray-200 bg-gray-50 focus:ring-2 focus:ring-accent/40 focus:border-accent outline-none transition text-gray-900">'
            . '<input type="email" name="email" placeholder="Your email" required class="w-full px-5 py-3.5 rounded-xl border border-gray-200 bg-gray-50 focus:ring-2 focus:ring-accent/40 focus:border-accent outline-none transition text-gray-900">'
            . '<textarea name="message" rows="4" placeholder="How can we help?" class="w-full px-5 py-3.5 rounded-xl border border-gray-200 bg-gray-50 focus:ring-2 focus:ring-accent/40 focus:border-accent outline-none transition text-gray-900 resize-none"></textarea>'
            . '<button type="submit" class="w-full px-8 py-4 bg-accent text-white font-semibold rounded-xl shadow-lg shadow-accent/25 hover:shadow-xl hover:-translate-y-0.5 transition-all duration-300">Send Message</button>'
            . '</form></div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_gallery($s, $i) {
        $id = 'section-' . ($i + 1) . '-gallery';
        $hl = esc_html($s['headline'] ?? 'Gallery');
        $bullets = is_array($s['bullets'] ?? null) ? $s['bullets'] : ['Project A', 'Project B', 'Project C', 'Project D'];
        $items = '';
        foreach ($bullets as $gi => $item) {
            $media_id = 'gallery-media-' . $i . '-' . $gi . '-' . wp_rand(1000, 9999);
            $seed = urlencode('gallery-' . $gi);
            $items .= '<div class="relative group overflow-hidden rounded-2xl aspect-square">'
                . '<img class="vmo-media-placeholder w-full h-full object-cover group-hover:scale-110 transition-transform duration-700" '
                . 'data-media-id="' . $media_id . '" data-type="image" loading="lazy" '
                . 'src="https://picsum.photos/seed/' . $seed . '/800/800" alt="' . esc_attr($item) . '" />'
                . '<div class="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-end p-6">'
                . '<p class="text-white font-semibold">' . esc_html($item) . '</p></div>'
                . self::replace_button_overlay($media_id)
                . '</div>';
        }
        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 bg-gray-50/50" data-vmo-section-type="gallery" data-vmo-animate>'
            . '<div class="max-w-7xl mx-auto px-6">'
            . '<h2 class="text-3xl md:text-5xl font-bold text-gray-900 tracking-tight text-center mb-16">' . $hl . '</h2>'
            . '<div class="grid grid-cols-2 lg:grid-cols-4 gap-4">' . $items . '</div>'
            . '</div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_team($s, $i) {
        $id = 'section-' . ($i + 1) . '-team';
        $hl = esc_html($s['headline'] ?? 'Meet the Team');
        $bullets = is_array($s['bullets'] ?? null) ? $s['bullets'] : ['Team Member A', 'Team Member B', 'Team Member C'];
        $cards = '';
        foreach ($bullets as $ti => $member) {
            $seed = urlencode('team-' . $ti);
            $cards .= '<div class="text-center">'
                . '<img class="w-32 h-32 rounded-full object-cover mx-auto shadow-lg" loading="lazy" '
                . 'src="https://picsum.photos/seed/' . $seed . '/300/300" alt="' . esc_attr($member) . '" />'
                . '<h3 class="mt-5 text-lg font-bold text-gray-900">' . esc_html($member) . '</h3>'
                . '<p class="text-gray-500 text-sm mt-1">Team Member</p></div>';
        }
        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 bg-white" data-vmo-section-type="team" data-vmo-animate>'
            . '<div class="max-w-7xl mx-auto px-6">'
            . '<h2 class="text-3xl md:text-5xl font-bold text-gray-900 tracking-tight text-center mb-16">' . $hl . '</h2>'
            . '<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-10">' . $cards . '</div>'
            . '</div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_faq($s, $i) {
        $id = 'section-' . ($i + 1) . '-faq';
        $hl = esc_html($s['headline'] ?? 'Frequently Asked Questions');
        $bullets = is_array($s['bullets'] ?? null) ? $s['bullets'] : ['How does this work?', 'What is the pricing?', 'Do you offer support?'];
        $items = '';
        foreach ($bullets as $fi => $question) {
            $items .= '<details class="group border border-gray-100 rounded-xl overflow-hidden" ' . ($fi === 0 ? 'open' : '') . '>'
                . '<summary class="flex items-center justify-between px-6 py-4 cursor-pointer font-semibold text-gray-900 hover:bg-gray-50 transition">'
                . esc_html($question) . '<span class="ml-4 text-gray-400 group-open:rotate-45 transition-transform duration-200 text-xl">+</span></summary>'
                . '<div class="px-6 pb-5 text-gray-600 leading-relaxed">Our team is here to help with all your needs. Contact us for detailed information.</div>'
                . '</details>';
        }
        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 bg-gray-50/50" data-vmo-section-type="faq" data-vmo-animate>'
            . '<div class="max-w-3xl mx-auto px-6">'
            . '<h2 class="text-3xl md:text-5xl font-bold text-gray-900 tracking-tight text-center mb-16">' . $hl . '</h2>'
            . '<div class="space-y-3">' . $items . '</div>'
            . '</div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_cta($s, $i) {
        $id = 'section-' . ($i + 1) . '-cta';
        $hl = esc_html($s['headline'] ?? 'Ready to Get Started?');
        $sub = esc_html($s['subheadline'] ?? '');
        $cta1 = esc_html($s['cta_primary'] ?? 'Get Started');
        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 bg-gradient-to-br from-gray-900 via-gray-800 to-gray-900 text-white" data-vmo-section-type="cta" data-vmo-animate>'
            . '<div class="max-w-4xl mx-auto px-6 text-center">'
            . '<h2 class="text-3xl md:text-5xl font-bold tracking-tight">' . $hl . '</h2>'
            . ($sub ? '<p class="mt-5 text-xl text-white/70">' . $sub . '</p>' : '')
            . '<a href="#" class="mt-10 inline-flex items-center px-10 py-5 bg-accent text-white font-bold text-lg rounded-2xl shadow-xl shadow-accent/30 hover:shadow-2xl hover:-translate-y-1 transition-all duration-300">' . $cta1 . '</a>'
            . '</div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    private static function section_default($s, $i) {
        $id = 'section-' . ($i + 1);
        $hl = esc_html($s['headline'] ?? 'Section');
        $sub = esc_html($s['subheadline'] ?? '');
        $body = esc_html($s['body'] ?? '');
        $media = self::media_placeholder('section', ($s['media'] ?? 'image'), $i);
        $swap = ($i % 2 === 1);
        $order = $swap ? 'md:order-last' : '';

        return '<!-- SECTION ' . ($i + 1) . ' -->'
            . '<section id="' . $id . '" class="py-24 lg:py-32 ' . ($i % 2 === 0 ? 'bg-white' : 'bg-gray-50/50') . '" data-vmo-section-type="default" data-vmo-animate>'
            . '<div class="max-w-7xl mx-auto px-6 grid grid-cols-1 md:grid-cols-2 gap-12 lg:gap-20 items-center">'
            . '<div class="' . $order . '">'
            . ($sub ? '<p class="text-accent font-semibold tracking-wide uppercase text-sm mb-3">' . $sub . '</p>' : '')
            . '<h2 class="text-3xl md:text-5xl font-bold text-gray-900 tracking-tight leading-tight">' . $hl . '</h2>'
            . ($body ? '<p class="mt-5 text-lg text-gray-600 leading-relaxed">' . $body . '</p>' : '')
            . '</div><div>' . $media . '</div>'
            . '</div></section>' . "\n<!-- END SECTION " . ($i + 1) . " -->\n";
    }

    /* ────────────────── CDN / STYLES / SCRIPTS ────────────────── */

    /**
     * Build CDN head tags (stylesheets + scripts + Tailwind config).
     */
    private static function build_cdn_head($tech, $primary = '#0f172a', $accent = '#0ea5e9') {
        $out = '';
        // Fonts
        $out .= '<link rel="preconnect" href="https://fonts.googleapis.com">';
        $out .= '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>';
        $out .= '<link rel="stylesheet" href="' . self::CDN['font'] . '">';
        // Tailwind CDN
        $out .= '<script src="' . self::CDN['tailwind'] . '"></script>';
        $out .= '<script>tailwind.config={theme:{extend:{colors:{primary:"' . $primary . '",accent:"' . $accent . '"},fontFamily:{sans:["Inter","system-ui","sans-serif"]}}}}</script>';
        // Swiper CSS
        $out .= '<link rel="stylesheet" href="' . self::CDN['swiper_css'] . '">';
        // AOS CSS
        $out .= '<link rel="stylesheet" href="' . self::CDN['aos_css'] . '">';
        return $out . "\n";
    }

    /**
     * Build base CSS that complements Tailwind.
     */
    private static function build_base_css($primary, $accent) {
        return <<<CSS
:root{--vmo-primary:{$primary};--vmo-accent:{$accent};}
html{scroll-behavior:smooth;}
body{margin:0;font-family:Inter,system-ui,-apple-system,sans-serif;-webkit-font-smoothing:antialiased;}
[data-vmo-animate]{opacity:0;transform:translateY(32px);transition:opacity .7s cubic-bezier(.16,1,.3,1),transform .7s cubic-bezier(.16,1,.3,1);}
[data-vmo-animate].vmo-visible{opacity:1;transform:translateY(0);}
.swiper-pagination-bullet-active{background:var(--vmo-accent)!important;}
.vmo-overlay-container{position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:1;}
CSS;
    }

    /**
     * Build initialization scripts (GSAP, Lenis, Swiper, AOS, media replace buttons).
     */
    private static function build_init_scripts() {
        return '<script src="' . self::CDN['gsap'] . '"></script>'
            . '<script src="' . self::CDN['scrolltrigger'] . '"></script>'
            . '<script src="' . self::CDN['lenis'] . '"></script>'
            . '<script src="' . self::CDN['swiper_js'] . '"></script>'
            . '<script src="' . self::CDN['aos_js'] . '"></script>'
            . '<script>'
            . self::build_init_js()
            . '</script>' . "\n";
    }

    /**
     * Build the JS initialization code for GSAP, Lenis, Swiper, AOS, overlays, and media replace.
     */
    private static function build_init_js() {
        return <<<'JS'
(function(){
  "use strict";

  /* ── Lenis smooth scroll ── */
  if(window.Lenis){
    var lenis=new Lenis({duration:1.2,easing:function(t){return Math.min(1,1.001-Math.pow(2,-10*t))},smoothWheel:true});
    function raf(time){lenis.raf(time);requestAnimationFrame(raf);}
    requestAnimationFrame(raf);
    if(window.gsap&&window.ScrollTrigger){
      lenis.on("scroll",function(){window.ScrollTrigger.update();});
      window.gsap.ticker.add(function(time){lenis.raf(time*1000);});
      window.gsap.ticker.lagSmoothing(0);
    }
  }

  /* ── GSAP ScrollTrigger reveal ── */
  if(window.gsap&&window.ScrollTrigger){
    window.gsap.registerPlugin(window.ScrollTrigger);
    document.querySelectorAll("[data-vmo-animate]").forEach(function(el){
      window.gsap.fromTo(el,{opacity:0,y:40},{opacity:1,y:0,duration:0.8,ease:"power3.out",scrollTrigger:{trigger:el,start:"top 88%",once:true}});
    });
  }else{
    /* Fallback: IntersectionObserver */
    var obs=new IntersectionObserver(function(entries){entries.forEach(function(e){if(e.isIntersecting){e.target.classList.add("vmo-visible");obs.unobserve(e.target);}});},{threshold:0.1});
    document.querySelectorAll("[data-vmo-animate]").forEach(function(el){obs.observe(el);});
  }

  /* ── AOS init ── */
  if(window.AOS){window.AOS.init({once:true,duration:700});}

  /* ── Swiper carousels ── */
  if(window.Swiper){
    document.querySelectorAll(".vmo-testimonial-swiper").forEach(function(el){
      new Swiper(el,{slidesPerView:1,spaceBetween:24,pagination:{el:el.querySelector(".swiper-pagination"),clickable:true},breakpoints:{768:{slidesPerView:2},1024:{slidesPerView:3}}});
    });
  }

  /* ── Media replace buttons ── */
  document.querySelectorAll(".vmo-replace-btn").forEach(function(btn){
    btn.addEventListener("click",function(e){
      e.preventDefault();
      e.stopPropagation();
      var mediaId=btn.getAttribute("data-replace-media");
      if(window.vmoOpenMediaPicker){window.vmoOpenMediaPicker(mediaId);}
      else if(window.parent&&window.parent.vmoOpenMediaPicker){window.parent.vmoOpenMediaPicker(mediaId);}
    });
  });

  /* ── Overlay containers ── */
  document.querySelectorAll("[data-vmo-section-type='hero']").forEach(function(hero){
    if(!hero.querySelector(".vmo-overlay-container")){
      var c=document.createElement("div");c.className="vmo-overlay-container";c.setAttribute("data-vmo-overlay-slot","hero");
      hero.insertBefore(c,hero.firstChild);
    }
  });

  /* ── VMO Pay buttons ── */
  document.querySelectorAll(".vmo-pay-btn").forEach(function(btn){
    btn.addEventListener("click",function(e){
      e.preventDefault();
      var product=btn.getAttribute("data-vmo-product")||"Product";
      if(window.vmoPayCheckout){window.vmoPayCheckout(product);}
      else{alert("VMO Pay checkout for: "+product);}
    });
  });

})();
JS;
    }
}
