<?php
/**
 * CastConductor Shortcodes
 * 
 * Provides shortcodes for embedding CastConductor previews on the front-end.
 * Renders a 1:1 mirror of the Scenes & Containers Stage.
 * 
 * @package CastConductor
 * @since 5.7.25
 */

if (!defined('ABSPATH')) {
    exit;
}

class CastConductor_Shortcodes {
    
    /**
     * 49-zone logo position map (matches scenes-stage/index.js LOGO_POSITION_MAP exactly)
     * Grid: 7 columns x 7 rows = 49 zones on 1280x720 canvas
     * Zone 25 (row 4, col 4) = TRUE CENTER
     */
    private static $logo_position_map = [
        // Row 1 (top)
        'zone-1'  => ['x' => 160,  'y' => 90],
        'zone-2'  => ['x' => 320,  'y' => 90],
        'zone-3'  => ['x' => 480,  'y' => 90],
        'zone-4'  => ['x' => 640,  'y' => 90],   // top center
        'zone-5'  => ['x' => 800,  'y' => 90],
        'zone-6'  => ['x' => 960,  'y' => 90],
        'zone-7'  => ['x' => 1120, 'y' => 90],
        // Row 2
        'zone-8'  => ['x' => 160,  'y' => 180],
        'zone-9'  => ['x' => 320,  'y' => 180],
        'zone-10' => ['x' => 480,  'y' => 180],
        'zone-11' => ['x' => 640,  'y' => 180],
        'zone-12' => ['x' => 800,  'y' => 180],
        'zone-13' => ['x' => 960,  'y' => 180],
        'zone-14' => ['x' => 1120, 'y' => 180],
        // Row 3
        'zone-15' => ['x' => 160,  'y' => 270],
        'zone-16' => ['x' => 320,  'y' => 270],
        'zone-17' => ['x' => 480,  'y' => 270],
        'zone-18' => ['x' => 640,  'y' => 270],
        'zone-19' => ['x' => 800,  'y' => 270],
        'zone-20' => ['x' => 960,  'y' => 270],
        'zone-21' => ['x' => 1120, 'y' => 270],
        // Row 4 (center row - zone-25 is TRUE CENTER)
        'zone-22' => ['x' => 160,  'y' => 360],
        'zone-23' => ['x' => 320,  'y' => 360],
        'zone-24' => ['x' => 480,  'y' => 360],
        'zone-25' => ['x' => 640,  'y' => 360],  // TRUE CENTER
        'zone-26' => ['x' => 800,  'y' => 360],
        'zone-27' => ['x' => 960,  'y' => 360],
        'zone-28' => ['x' => 1120, 'y' => 360],
        // Row 5
        'zone-29' => ['x' => 160,  'y' => 450],
        'zone-30' => ['x' => 320,  'y' => 450],
        'zone-31' => ['x' => 480,  'y' => 450],
        'zone-32' => ['x' => 640,  'y' => 450],
        'zone-33' => ['x' => 800,  'y' => 450],
        'zone-34' => ['x' => 960,  'y' => 450],
        'zone-35' => ['x' => 1120, 'y' => 450],
        // Row 6
        'zone-36' => ['x' => 160,  'y' => 540],
        'zone-37' => ['x' => 320,  'y' => 540],
        'zone-38' => ['x' => 480,  'y' => 540],
        'zone-39' => ['x' => 640,  'y' => 540],
        'zone-40' => ['x' => 800,  'y' => 540],
        'zone-41' => ['x' => 960,  'y' => 540],
        'zone-42' => ['x' => 1120, 'y' => 540],
        // Row 7 (bottom)
        'zone-43' => ['x' => 160,  'y' => 630],
        'zone-44' => ['x' => 320,  'y' => 630],
        'zone-45' => ['x' => 480,  'y' => 630],
        'zone-46' => ['x' => 640,  'y' => 630],  // bottom center
        'zone-47' => ['x' => 800,  'y' => 630],
        'zone-48' => ['x' => 960,  'y' => 630],
        'zone-49' => ['x' => 1120, 'y' => 630],
        // Semantic aliases
        'center'        => ['x' => 640,  'y' => 360],
        'top-center'    => ['x' => 640,  'y' => 90],
        'bottom-center' => ['x' => 640,  'y' => 630],
        'left-center'   => ['x' => 160,  'y' => 360],
        'right-center'  => ['x' => 1120, 'y' => 360],
    ];
    
    /**
     * Initialize shortcodes
     */
    public static function init() {
        add_shortcode('castconductor_preview', [__CLASS__, 'render_preview_shortcode']);
        add_shortcode('cc_preview', [__CLASS__, 'render_preview_shortcode']); // Alias
    }
    
    /**
     * Render the scene preview shortcode - 1:1 mirror of Scenes & Containers Stage
     * 
     * Usage: [castconductor_preview] or [cc_preview]
     * 
     * Attributes:
     * - scene_id: Specific scene ID (default: active scene)
     * - width: Container width (default: 960px)
     * - autoplay: Auto-rotate content (default: true)
     * - interval: Override rotation interval in seconds (optional - uses scene intervals by default)
     * 
     * @param array $atts Shortcode attributes
     * @return string HTML output
     */
    public static function render_preview_shortcode($atts) {
        $atts = shortcode_atts([
            'scene_id' => null,
            'width' => '960',
            'autoplay' => 'true',
            'interval' => null,  // null = use scene's configured intervals
        ], $atts, 'castconductor_preview');
        
        // Get scene ID
        $scene_id = $atts['scene_id'] ? intval($atts['scene_id']) : intval(get_option('castconductor_active_scene_id', 0));
        
        if (!$scene_id) {
            return '<div class="cc-preview-error" style="padding:20px;background:#1e1e1e;color:#ef4444;border-radius:8px;text-align:center;">No active scene configured.</div>';
        }
        
        // Fetch scene data
        global $wpdb;
        $db = new CastConductor_Database();
        $scenes_table = $db->get_table_name('scenes');
        $scene_containers_table = $db->get_table_name('scene_containers');
        $containers_table = $db->get_table_name('containers');
        $content_blocks_table = $db->get_table_name('content_blocks');
        
        $scene = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$scenes_table} WHERE id = %d",
            $scene_id
        ));
        
        if (!$scene) {
            return '<div class="cc-preview-error" style="padding:20px;background:#1e1e1e;color:#ef4444;border-radius:8px;text-align:center;">Scene not found.</div>';
        }
        
        // Parse scene config (exactly like scenes-stage/index.js)
        $branding = !empty($scene->branding) ? json_decode($scene->branding, true) : [];
        $background = !empty($scene->background) ? json_decode($scene->background, true) : [];
        
        // Get scene's rotation interval (for content cycling)
        $scene_rotation_interval = intval($scene->rotation_interval ?? get_option('castconductor_scene_rotation_interval', 60));
        
        // Get containers assigned to this scene (matching the JS query)
        $scene_containers = $wpdb->get_results($wpdb->prepare(
            "SELECT sc.*, c.name as container_name, c.position, c.width, c.height, c.x_position, c.y_position, c.z_index
             FROM {$scene_containers_table} sc
             JOIN {$containers_table} c ON sc.container_id = c.id
             WHERE sc.scene_id = %d AND sc.enabled = 1
             ORDER BY c.z_index ASC",
            $scene_id
        ));
        
        // Build preview data
        $preview_data = [
            'scene_id' => $scene_id,
            'scene_name' => $scene->name,
            'branding' => $branding,
            'background' => $background,
            'containers' => [],
            'scene_interval' => $scene_rotation_interval * 1000,  // ms
            'autoplay' => $atts['autoplay'] === 'true',
        ];
        
        // Process each container
        foreach ($scene_containers as $sc) {
            $overrides = !empty($sc->overrides) ? json_decode($sc->overrides, true) : [];
            $zones_data = !empty($sc->zones) ? json_decode($sc->zones, true) : [];
            
            // Container rect (with overrides if set)
            $rect = $overrides['rect'] ?? [
                'x' => intval($sc->x_position),
                'y' => intval($sc->y_position),
                'width' => intval($sc->width),
                'height' => intval($sc->height),
            ];
            
            $container_data = [
                'id' => $sc->container_id,
                'name' => $sc->container_name,
                'position' => $sc->position,
                'z_index' => intval($sc->z_index ?? 0),
                'rect' => $rect,
                'zones' => [],
            ];
            
            // Process zones and their block assignments
            foreach ($zones_data as $zone_id => $zone_info) {
                $assignments = $zone_info['assignments'] ?? [];
                $zone_blocks = [];
                
                foreach ($assignments as $assignment) {
                    $block_id = $assignment['block_id'] ?? null;
                    if (!$block_id) continue;
                    
                    // Fetch content block
                    $block = $wpdb->get_row($wpdb->prepare(
                        "SELECT * FROM {$content_blocks_table} WHERE id = %d AND enabled = 1",
                        $block_id
                    ));
                    
                    if ($block) {
                        // Get preview HTML using the same method as canvas-editor/preview endpoint
                        $preview_html = self::get_block_preview_html($block, $rect);
                        
                        // Use assignment interval, fallback to scene interval
                        $block_interval = !empty($assignment['interval']) 
                            ? intval($assignment['interval']) * 1000 
                            : $scene_rotation_interval * 1000;
                        
                        // Override with shortcode attribute if specified
                        if ($atts['interval'] !== null) {
                            $block_interval = intval($atts['interval']) * 1000;
                        }
                        
                        $zone_blocks[] = [
                            'id' => $block->id,
                            'name' => $block->name,
                            'type' => $block->type,
                            'weight' => floatval($assignment['weight'] ?? $assignment['rotation_percentage'] ?? 100),
                            'interval' => $block_interval,
                            'html' => $preview_html,
                        ];
                    }
                }
                
                if (!empty($zone_blocks)) {
                    $container_data['zones'][$zone_id] = $zone_blocks;
                }
            }
            
            $preview_data['containers'][] = $container_data;
        }
        
        // Generate unique ID for this instance
        $instance_id = 'cc-preview-' . wp_generate_uuid4();
        
        // Enqueue Lexend font (matches content block typography)
        wp_enqueue_style(
            'google-fonts-lexend',
            'https://fonts.googleapis.com/css2?family=Lexend:wght@300;400;500;600;700&display=swap',
            [],
            null
        );
        
        // Enqueue styles
        wp_enqueue_style(
            'castconductor-preview-shortcode',
            plugins_url('../assets/css/preview-shortcode.css', __FILE__),
            ['google-fonts-lexend'],
            filemtime(CASTCONDUCTOR_PLUGIN_DIR . 'assets/css/preview-shortcode.css')
        );
        
        // Build HTML
        $width = intval($atts['width']);
        $scale = $width / 1280;
        $height = round(720 * $scale);
        
        ob_start();
        ?>
        <div id="<?php echo esc_attr($instance_id); ?>" class="cc-frontend-preview" style="width:<?php echo $width; ?>px; height:<?php echo $height; ?>px;">
            <div class="cc-preview-canvas" style="transform: scale(<?php echo $scale; ?>);">
                
                <!-- Background Layer (z-index: 1) -->
                <div class="cc-preview-background" style="z-index:1;">
                    <?php echo self::render_background_html($background); ?>
                </div>
                
                <!-- Containers Layer (z-index: 10+) -->
                <div class="cc-preview-containers" style="z-index:10;">
                    <?php foreach ($preview_data['containers'] as $container): ?>
                        <?php 
                        $rect = $container['rect'];
                        $style = sprintf(
                            'position:absolute;left:%dpx;top:%dpx;width:%dpx;height:%dpx;z-index:%d;',
                            $rect['x'], $rect['y'], $rect['width'], $rect['height'],
                            10 + $container['z_index']
                        );
                        ?>
                        <div class="cc-preview-container" 
                             data-container-id="<?php echo esc_attr($container['id']); ?>"
                             data-container-name="<?php echo esc_attr($container['name']); ?>"
                             style="<?php echo esc_attr($style); ?>">
                            
                            <?php foreach ($container['zones'] as $zone_id => $blocks): ?>
                                <div class="cc-preview-zone" data-zone-id="<?php echo esc_attr($zone_id); ?>">
                                    <?php foreach ($blocks as $idx => $block): ?>
                                        <div class="cc-preview-block <?php echo $idx === 0 ? 'active' : ''; ?>"
                                             data-block-id="<?php echo esc_attr($block['id']); ?>"
                                             data-interval="<?php echo esc_attr($block['interval']); ?>"
                                             data-weight="<?php echo esc_attr($block['weight']); ?>">
                                            <?php echo $block['html']; ?>
                                        </div>
                                    <?php endforeach; ?>
                                </div>
                            <?php endforeach; ?>
                            
                        </div>
                    <?php endforeach; ?>
                </div>
                
                <!-- Branding Layer (z-index: 100 - always on top) -->
                <?php echo self::render_branding_html($branding); ?>
                
            </div>
        </div>
        
        <?php if ($preview_data['autoplay']): ?>
        <script>
        (function() {
            const container = document.getElementById('<?php echo esc_js($instance_id); ?>');
            if (!container) return;
            
            // Weighted random selection (matches scenes-stage pickNextByWeights)
            function pickByWeight(blocks) {
                if (!blocks || blocks.length === 0) return null;
                if (blocks.length === 1) return blocks[0];
                
                const totalWeight = blocks.reduce((sum, b) => sum + (parseFloat(b.dataset.weight) || 100), 0);
                let random = Math.random() * totalWeight;
                
                for (const block of blocks) {
                    random -= parseFloat(block.dataset.weight) || 100;
                    if (random <= 0) return block;
                }
                return blocks[0];
            }
            
            // Content rotation per zone (respects individual block intervals)
            const zones = container.querySelectorAll('.cc-preview-zone');
            zones.forEach(zone => {
                const blocks = Array.from(zone.querySelectorAll('.cc-preview-block'));
                if (blocks.length <= 1) return;
                
                let currentBlock = zone.querySelector('.cc-preview-block.active');
                
                function rotateContent() {
                    const nextBlock = pickByWeight(blocks.filter(b => b !== currentBlock));
                    if (!nextBlock || nextBlock === currentBlock) return;
                    
                    // Fade transition
                    currentBlock.classList.remove('active');
                    nextBlock.classList.add('active');
                    currentBlock = nextBlock;
                    
                    // Schedule next rotation using THIS block's interval
                    const interval = parseInt(nextBlock.dataset.interval) || 60000;
                    setTimeout(rotateContent, interval);
                }
                
                // Start with the first block's interval
                const firstInterval = parseInt(currentBlock?.dataset.interval) || 60000;
                setTimeout(rotateContent, firstInterval);
            });
        })();
        </script>
        <?php endif; ?>
        <?php
        
        return ob_get_clean();
    }
    
    /**
     * Get block preview HTML (mirrors canvas-editor/preview endpoint)
     */
    private static function get_block_preview_html($block, $frame = null) {
        // Include controllers
        require_once CASTCONDUCTOR_PLUGIN_DIR . 'includes/api/class-content-blocks-controller.php';
        require_once CASTCONDUCTOR_PLUGIN_DIR . 'includes/api/class-canvas-editor-controller.php';
        
        $visual_config = !empty($block->visual_config) ? json_decode($block->visual_config, true) : [];
        
        // Fetch live data
        $cbc = new CastConductor_Content_Blocks_Controller();
        $live_data = $cbc->fetch_live_data($block);
        
        // Get preview from canvas editor controller
        $cec = new CastConductor_Canvas_Editor_Controller();
        $preview_html = $cec->get_preview_html_for_block($block, $visual_config, $live_data);
        
        return $preview_html;
    }
    
    /**
     * Render background HTML (matches applyBackground in scenes-stage)
     */
    private static function render_background_html($background) {
        if (!empty($background['sources'][0])) {
            // Background image
            return sprintf(
                '<img src="%s" alt="" style="width:100%%;height:100%%;object-fit:cover;">',
                esc_url($background['sources'][0])
            );
        } elseif (!empty($background['color'])) {
            // Solid color
            return sprintf(
                '<div style="width:100%%;height:100%%;background:%s;"></div>',
                esc_attr($background['color'])
            );
        } else {
            // Default gradient
            return '<div style="width:100%;height:100%;background:linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);"></div>';
        }
    }
    
    /**
     * Render branding HTML (matches applyBranding in scenes-stage exactly)
     * Uses the 49-zone grid system
     */
    private static function render_branding_html($branding) {
        // Get logo source (same priority as JS)
        $src = null;
        
        if (!empty($branding['animated_center_logo']['url'])) {
            $src = $branding['animated_center_logo']['url'];
        } elseif (!empty($branding['animated_center_logo']['src'])) {
            $src = $branding['animated_center_logo']['src'];
        } elseif (is_string($branding['logo'] ?? null)) {
            $src = $branding['logo'];
        } elseif (!empty($branding['logo']['src'])) {
            $src = $branding['logo']['src'];
        } elseif (!empty($branding['logo']['url'])) {
            $src = $branding['logo']['url'];
        } elseif (!empty($branding['center']['logo']['src'])) {
            $src = $branding['center']['logo']['src'];
        } elseif (!empty($branding['center']['logo']['url'])) {
            $src = $branding['center']['logo']['url'];
        }
        
        if (!$src) {
            return '';  // No logo to render
        }
        
        // Get scale and position (matches JS defaults)
        $scale = isset($branding['logo_scale']) ? floatval($branding['logo_scale']) : 70;
        $position = $branding['logo_position'] ?? 'center';
        
        // Get position from 49-zone map
        $pos = self::$logo_position_map[$position] ?? self::$logo_position_map['center'];
        
        // Animation: center positions get the float-pulse animation (same logic as JS)
        // Check for 'center', 'zone-25', or zone-11 (old center) - be permissive
        $center_positions = ['center', 'zone-25', 'zone-11', 'zone-17'];
        $is_animated = in_array($position, $center_positions, true);
        $anim_class = $is_animated ? 'cc-logo-animated' : '';
        
        // Logo scale: use the full scale value as max-width percentage
        // The JS does: maxWidth: `${scale}%` where scale defaults to 70
        $logo_max_width = max(10, min(100, $scale)); // Clamp between 10-100%
        
        return sprintf(
            '<div class="cc-preview-branding %s" style="position:absolute;z-index:100;left:%dpx;top:%dpx;transform:translate(-50%%,-50%%);pointer-events:none;">
                <img src="%s" alt="branding" style="max-width:%d%%;height:auto;">
            </div>',
            esc_attr($anim_class),
            intval($pos['x']),
            intval($pos['y']),
            esc_url($src),
            intval($logo_max_width)
        );
    }
}

// Initialize
CastConductor_Shortcodes::init();
