<?php
if (!defined('ABSPATH')) exit;

class VMO_Visual_Preset_Registry {
    private static $instance = null;
    private $presets = array();

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

    private function __construct() {
        $this->presets = array(
            'cinematic_service_hero' => array(
                'key' => 'cinematic_service_hero',
                'label' => 'Cinematic Service Hero',
                'fit' => array('services', 'consulting', 'local business', 'professional services'),
                'required_signals' => array('full-viewport hero', 'early trust proof', 'layered media', 'premium CTA cluster', 'scroll reveal'),
                'prompt_directives' => array(
                    'Open with a cinematic full-viewport hero that combines brand, navigation, proof, media, and CTA in one composed scene.',
                    'Use editorial service storytelling, high-trust proof blocks, and an action-oriented contact path.',
                    'Avoid generic agency brochure structure and bland split hero layouts.'
                ),
                'motion_requirements' => array('scroll reveal', 'mouse-reactive parallax', 'floating proof panels'),
                'media_requirements' => array('hero image or video layer', 'service proof media', 'customer outcome visual'),
                'mobile_requirements' => array('compressed hero scene', 'sticky primary CTA', 'stacked proof cards')
            ),
            'fullscreen_minisite' => array(
                'key' => 'fullscreen_minisite',
                'label' => 'Fullscreen Mini-Site',
                'fit' => array('launch', 'event', 'portfolio', 'campaign', 'premium offer'),
                'required_signals' => array('full-screen sections', 'snap-like progression', 'immersive media', 'minimal chrome', 'strong final CTA'),
                'prompt_directives' => array(
                    'Build a sequence of full-screen editorial sections that feel like a guided premium experience.',
                    'Use minimal but usable navigation and make every viewport feel intentionally composed.',
                    'Keep the site simple to navigate while preserving immersive pacing.'
                ),
                'motion_requirements' => array('section-to-section reveal', 'scroll-controlled transitions', 'progress indicator'),
                'media_requirements' => array('full-bleed scene media', 'supporting detail media'),
                'mobile_requirements' => array('shorter sections', 'visible next-step affordance', 'persistent nav/CTA')
            ),
            'product_demo_scroll' => array(
                'key' => 'product_demo_scroll',
                'label' => 'Scroll-Controlled Product Demo',
                'fit' => array('saas', 'software', 'app', 'platform', 'technology'),
                'required_signals' => array('product stage hero', 'scroll-led demo', 'feature proof', 'interface closeups', 'conversion CTA'),
                'prompt_directives' => array(
                    'Make the product or platform visible in the first viewport through interface-led media composition.',
                    'Use scroll-controlled storytelling to explain the product step by step.',
                    'Prioritize dense, scannable information and credible product proof over decorative panels.'
                ),
                'motion_requirements' => array('sticky demo panel', 'step-driven animation', 'horizontal feature rail'),
                'media_requirements' => array('interface mock media', 'workflow media', 'proof/dashboard media'),
                'mobile_requirements' => array('single-column demo steps', 'swipeable feature cards', 'compact CTA bar')
            ),
            'ecommerce_storytelling' => array(
                'key' => 'ecommerce_storytelling',
                'label' => 'Ecommerce Storytelling',
                'fit' => array('ecommerce', 'products', 'shop', 'store', 'retail'),
                'required_signals' => array('product-first hero', 'story-led collection', 'buy path', 'trust badges', 'detail sections'),
                'prompt_directives' => array(
                    'Lead with the product or collection as the dominant first-viewport signal.',
                    'Blend editorial product storytelling with clear shopping actions and trust proof.',
                    'Use product detail sections that make items inspectable and easy to buy.'
                ),
                'motion_requirements' => array('product hover states', 'collection reveal', 'sticky purchase CTA'),
                'media_requirements' => array('hero product media', 'collection/product cards', 'lifestyle detail media'),
                'mobile_requirements' => array('quick buy CTA', 'large product imagery', 'simple variant/detail path')
            ),
            'restaurant_food_experience' => array(
                'key' => 'restaurant_food_experience',
                'label' => 'Restaurant and Food Experience',
                'fit' => array('restaurant', 'food', 'cafe', 'bar', 'bakery', 'catering'),
                'required_signals' => array('food hero', 'menu/story sections', 'reservation CTA', 'location/contact', 'social proof'),
                'prompt_directives' => array(
                    'Make food, venue, atmosphere, and reservation/contact actions visible immediately.',
                    'Use sensory menu storytelling rather than a flat menu list.',
                    'Prioritize mobile reservation, directions, phone, hours, and order actions.'
                ),
                'motion_requirements' => array('menu reveal', 'gallery parallax', 'sticky reservation CTA'),
                'media_requirements' => array('hero food media', 'menu item media', 'venue/location media'),
                'mobile_requirements' => array('tap-to-call', 'sticky reserve/order button', 'hours/location block')
            ),
            'fashion_editorial_lookbook' => array(
                'key' => 'fashion_editorial_lookbook',
                'label' => 'Fashion Editorial Lookbook',
                'fit' => array('fashion', 'beauty', 'apparel', 'lifestyle', 'luxury'),
                'required_signals' => array('editorial hero', 'lookbook grid', 'collection story', 'product detail', 'premium nav'),
                'prompt_directives' => array(
                    'Use an editorial layout with asymmetry, immersive imagery, and collection storytelling.',
                    'Make the brand/product visually inspectable in the first viewport.',
                    'Keep typography restrained and high-end, with clear shopping or booking actions.'
                ),
                'motion_requirements' => array('lookbook reveal', 'hover detail', 'horizontal collection rail'),
                'media_requirements' => array('editorial hero media', 'lookbook media', 'detail/product media'),
                'mobile_requirements' => array('large vertical imagery', 'swipeable looks', 'simple shop/book path')
            ),
            'wine_product_detail' => array(
                'key' => 'wine_product_detail',
                'label' => 'Wine/Product Click-to-Detail',
                'fit' => array('wine', 'beverage', 'distillery', 'product catalog', 'specialty goods'),
                'required_signals' => array('product bottle/object hero', 'click-to-detail cards', 'tasting/detail notes', 'purchase/reserve CTA', 'story proof'),
                'prompt_directives' => array(
                    'Center the product object and make detail exploration feel tactile and premium.',
                    'Use click-to-detail or expandable product cards for notes, origin, specs, and purchase/reservation actions.',
                    'Avoid generic catalog grids without story or inspection.'
                ),
                'motion_requirements' => array('product detail reveal', 'spotlight hover', 'sticky product CTA'),
                'media_requirements' => array('object hero media', 'product detail media', 'story/origin media'),
                'mobile_requirements' => array('expandable product details', 'large product media', 'sticky purchase/reserve CTA')
            ),
            'glassmorphism_hero' => array(
                'key' => 'glassmorphism_hero',
                'label' => 'Glassmorphism Hero',
                'fit' => array('premium', 'finance', 'technology', 'wellness', 'modern service'),
                'required_signals' => array('glass hero layers', 'floating panels', 'soft depth', 'trust proof', 'premium CTA'),
                'prompt_directives' => array(
                    'Use glass surfaces as functional interface layers, not decorative blobs.',
                    'Pair translucent panels with real content, proof, media, and CTA actions.',
                    'Keep text legible and avoid overusing one-note dark blue/purple palettes.'
                ),
                'motion_requirements' => array('floating panels', 'soft parallax', 'hover elevation'),
                'media_requirements' => array('depth hero media', 'proof/interface media'),
                'mobile_requirements' => array('legible glass cards', 'reduced blur layers', 'clear CTA stack')
            )
        );

        $this->presets = array_merge($this->presets, $this->build_v2_blueprint_presets());
    }

    public function all() {
        return $this->presets;
    }

    public function get($preset_key) {
        $preset_key = sanitize_key((string) $preset_key);
        return $this->presets[$preset_key] ?? $this->presets['cinematic_service_hero'];
    }

    public function build_generation_context(array $payload, $source = 'canonical') {
        $requested = $this->extract_requested_preset($payload);
        $selected_key = $requested ?: $this->recommend_key($payload);
        $preset = $this->get($selected_key);

        return array(
            'source' => sanitize_key((string) $source),
            'registry_version' => '2026-04-30',
            'selected_visual_preset' => $preset['key'],
            'visual_preset_label' => $preset['label'],
            'visual_preset' => $preset,
            'required_premium_signals' => $preset['required_signals'],
            'motion_requirements' => $preset['motion_requirements'],
            'media_requirements' => $preset['media_requirements'],
            'mobile_requirements' => $preset['mobile_requirements'],
        );
    }

    public function render_generation_brief(array $context) {
        $preset = is_array($context['visual_preset'] ?? null) ? $context['visual_preset'] : $this->get($context['selected_visual_preset'] ?? 'cinematic_service_hero');
        $lines = array();
        $lines[] = "CANONICAL VISUAL EXPERIENCE PRESET:";
        $lines[] = '- Preset: ' . $preset['label'] . ' (' . $preset['key'] . ')';
        $lines[] = '- Required Signals: ' . implode(', ', $preset['required_signals']);
        $lines[] = '- Motion Requirements: ' . implode(', ', $preset['motion_requirements']);
        $lines[] = '- Media Requirements: ' . implode(', ', $preset['media_requirements']);
        $lines[] = '- Mobile Requirements: ' . implode(', ', $preset['mobile_requirements']);
        if (!empty($preset['component_requirements']) && is_array($preset['component_requirements'])) {
            $lines[] = '- Component Requirements: ' . implode(', ', $preset['component_requirements']);
        }
        if (!empty($preset['qa_expectations']) && is_array($preset['qa_expectations'])) {
            $lines[] = '- QA Expectations: ' . implode(', ', $preset['qa_expectations']);
        }
        foreach ($preset['prompt_directives'] as $directive) {
            $lines[] = '- ' . $directive;
        }
        $lines[] = '';
        return implode("\n", $lines);
    }

    private function build_v2_blueprint_presets() {
        $groups = array(
            'hero' => array(
                'layered_cinematic_hero' => 'Layered Cinematic Hero',
                'multi_layer_video_hero' => 'Multi-Layer Video Hero',
                'scroll_zoom_product_reveal' => 'Scroll Zoom Product Reveal',
                'persistent_scene_subject_swap' => 'Persistent Scene Subject Swap',
                'mouse_reactive_parallax_hero' => 'Mouse-Reactive Parallax Hero',
                'glassmorphism_campaign_hero' => 'Glassmorphism Campaign Hero',
                'special_effect_signature_reveal' => 'Special-Effect Signature Reveal',
                'food_appetite_hero' => 'Food Appetite Hero',
                'burger_product_hero' => 'Burger/Product Hero',
                'fashion_editorial_hero' => 'Fashion Editorial Hero',
                'wine_ecommerce_hero' => 'Wine Ecommerce Hero',
                'fullscreen_minisite_hero' => 'Full-Screen Mini-Site Hero',
                'video_loop_menu_hero' => 'Video Loop Menu Hero',
                'transparent_subject_video_hero' => 'Transparent Subject Video Hero',
                'boot_to_hero_intro' => 'Boot-to-Hero Intro',
            ),
            'menu' => array(
                'floating_glass_capsule_menu' => 'Floating Glass Capsule Menu',
                'transparent_frosted_menu' => 'Transparent Frosted Menu',
                'dark_glass_overlay_menu' => 'Dark Glass Overlay Menu',
                'video_hero_integrated_menu' => 'Video Hero Integrated Menu',
                'image_preview_fullscreen_menu' => 'Image Preview Fullscreen Menu',
                'mobile_bottom_pill_menu' => 'Mobile Bottom Pill Menu',
                'luxury_reserve_menu' => 'Luxury Reserve Menu',
                'restaurant_order_reserve_menu' => 'Restaurant Order/Reserve Menu',
                'ecommerce_sticky_buy_menu' => 'Ecommerce Sticky Buy Menu',
                'mini_site_panel_menu' => 'Mini-Site Panel Menu',
            ),
            'ecommerce_product' => array(
                'product_story_scroll' => 'Product Story Scroll',
                'wine_click_to_detail' => 'Wine Click-to-Detail',
                'fashion_lookbook_grid' => 'Fashion Lookbook Grid',
                'food_order_slider' => 'Food Order Slider',
                'product_flavor_selector' => 'Product Flavor Selector',
                'quick_view_modal' => 'Quick View Modal',
                'scroll_reveal_product_cards' => 'Scroll Reveal Product Cards',
                'product_ingredient_float_layers' => 'Product Ingredient Float Layers',
                'interactive_product_comparison' => 'Interactive Product Comparison',
            ),
            'motion' => array(
                'gsap_fade_rise' => 'GSAP Fade Rise',
                'scrolltrigger_pin_story' => 'ScrollTrigger Pin Story',
                'parallax_depth_stack' => 'Parallax Depth Stack',
                'mouse_reactive_depth' => 'Mouse Reactive Depth',
                'scroll_synced_video' => 'Scroll-Synced Video',
                'card_stack_reveal' => 'Card Stack Reveal',
                'horizontal_gallery_scroll' => 'Horizontal Gallery Scroll',
                'section_snap_slide' => 'Section Snap Slide',
                'product_float_loop' => 'Product Float Loop',
                'boot_screen_intro' => 'Boot Screen Intro',
                'full_screen_panel_transition' => 'Full-Screen Panel Transition',
                'click_to_detail_transition' => 'Click-to-Detail Transition',
                'glass_panel_hover_lift' => 'Glass Panel Hover Lift',
            ),
        );

        $presets = array();
        foreach ($groups as $category => $items) {
            foreach ($items as $key => $label) {
                $presets[$key] = $this->make_v2_preset($key, $label, $category);
            }
        }
        return $presets;
    }

    private function make_v2_preset($key, $label, $category) {
        $base = array(
            'hero' => array(
                'fit' => array('premium', 'launch', 'campaign', 'product', 'restaurant', 'fashion', 'wine', 'service'),
                'signals' => array('three-plus hero layers', 'clear focal subject', 'premium CTA layer', 'mobile hero fallback', 'visual benchmark reflected'),
                'components' => array('hero_scene', 'foreground_content_layer', 'cta_cluster', 'mobile_hero_variant'),
                'motion' => array('entrance timeline', 'parallax depth stack', 'reduced-motion fallback'),
                'media' => array('hero focal media', 'mobile poster/crop', 'atmospheric or depth layer'),
                'mobile' => array('simplified layer count', 'sticky CTA', 'tap-safe focal content'),
            ),
            'menu' => array(
                'fit' => array('premium navigation', 'mini-site', 'restaurant', 'ecommerce', 'campaign'),
                'signals' => array('premium menu selected', 'high z-index', 'accessible labels', 'CTA-forward navigation', 'mobile-specific menu'),
                'components' => array('desktop_menu', 'mobile_menu', 'menu_cta', 'focus_state'),
                'motion' => array('menu reveal', 'hover/tap affordance', 'reduced-motion fallback'),
                'media' => array('menu background context where appropriate', 'icon/logo asset'),
                'mobile' => array('bottom pill or clear overlay', 'tap targets', 'does not block CTAs'),
            ),
            'ecommerce_product' => array(
                'fit' => array('ecommerce', 'products', 'shop', 'wine', 'fashion', 'food', 'retail'),
                'signals' => array('product storytelling', 'detail interaction', 'buy path', 'product media complete', 'tracking hooks'),
                'components' => array('product_story_section', 'quick_view_or_detail_panel', 'checkout_cta', 'product_tracking'),
                'motion' => array('product reveal', 'click-to-detail transition', 'card/slider motion'),
                'media' => array('product image set', 'detail closeups', 'mobile product fallback'),
                'mobile' => array('swipe product cards', 'sticky buy CTA', 'fast product inspection'),
            ),
            'motion' => array(
                'fit' => array('premium motion', 'interactive storytelling', 'mini-site', 'product demo'),
                'signals' => array('approved motion preset', 'clear interaction purpose', 'performance budget', 'reduced-motion fallback', 'clicks remain unblocked'),
                'components' => array('motion_runtime_config', 'section_triggers', 'mobile_motion_fallback'),
                'motion' => array('GSAP/ScrollTrigger-safe preset', 'event-scoped animation', 'reduced-motion fallback'),
                'media' => array('poster/fallback when motion uses video', 'visual anchors for animation'),
                'mobile' => array('motion simplified', 'no heavy scrub on mobile', 'tap-first alternatives'),
            ),
        );

        $config = $base[$category];
        return array(
            'key' => $key,
            'label' => $label,
            'category' => $category,
            'fit' => $config['fit'],
            'required_signals' => $config['signals'],
            'component_requirements' => $config['components'],
            'prompt_directives' => array(
                'Use the approved ' . $label . ' preset as a v2.0 benchmark family, not as copied reference design.',
                'Keep the experience visually premium while preserving obvious navigation and conversion actions.',
                'Render through WordPress-safe, scoped, editable component state and block preview if required media or QA is incomplete.'
            ),
            'motion_requirements' => $config['motion'],
            'media_requirements' => $config['media'],
            'mobile_requirements' => $config['mobile'],
            'qa_expectations' => array('passes v2.0 threshold table', 'no placeholders in review preview', 'dashboard and tracking contract present'),
        );
    }

    private function extract_requested_preset(array $payload) {
        $candidates = array(
            $payload['visual_preset'] ?? '',
            $payload['requested_preset'] ?? '',
            $payload['preset'] ?? '',
            $payload['canonical_generation_context']['selected_visual_preset'] ?? '',
            $payload['responses']['visual_preset'] ?? '',
            $payload['extracted_information']['visual_preset'] ?? '',
            $payload['extracted_information']['websiteVisualPreset'] ?? '',
        );
        foreach ($candidates as $candidate) {
            $candidate = sanitize_key((string) $candidate);
            if ($candidate !== '' && isset($this->presets[$candidate])) {
                return $candidate;
            }
        }
        return '';
    }

    private function recommend_key(array $payload) {
        $signal = strtolower(wp_json_encode($payload));

        $rules = array(
            'food_appetite_hero' => array('restaurant', 'food', 'cafe', 'bar ', 'bakery', 'catering', 'reservation', 'menu'),
            'wine_ecommerce_hero' => array('wine', 'winery', 'vineyard', 'beverage', 'distillery', 'brewery', 'tasting'),
            'fashion_editorial_hero' => array('fashion', 'apparel', 'clothing', 'beauty', 'lookbook', 'luxury', 'lifestyle'),
            'scroll_zoom_product_reveal' => array('saas', 'software', 'app', 'platform', 'dashboard', 'technology', 'demo'),
            'product_story_scroll' => array('ecommerce', 'e-commerce', 'shop', 'store', 'retail', 'product', 'products', 'buy now'),
            'fullscreen_minisite_hero' => array('event', 'launch', 'campaign', 'portfolio', 'mini-site', 'minisite', 'immersive'),
            'glassmorphism_campaign_hero' => array('glass', 'glassmorphism', 'premium modern', 'finance', 'fintech'),
        );

        foreach ($rules as $preset_key => $keywords) {
            foreach ($keywords as $keyword) {
                if ($keyword !== '' && strpos($signal, $keyword) !== false) {
                    return $preset_key;
                }
            }
        }

        return 'cinematic_service_hero';
    }
}

if (!function_exists('vmo_get_visual_preset_registry')) {
    function vmo_get_visual_preset_registry() {
        return VMO_Visual_Preset_Registry::get_instance();
    }
}