/**
 * VMO Video Generation UI
 * Interface for generating videos with Sora and managing 360° product viewers
 * 
 * @package VMO_AI_Builder
 * @since 9.0.0
 */

(function() {
    'use strict';

    class VMOVideoGenerator {
        constructor() {
            this.activeJobs = new Map();
            this.pollInterval = 10000; // 10 seconds
            
            // Bind AJAX handlers
            this.nonce = typeof vmo_ajax !== 'undefined' ? vmo_ajax.nonce : '';
            this.ajaxUrl = typeof vmo_ajax !== 'undefined' ? vmo_ajax.ajax_url : '/wp-admin/admin-ajax.php';
        }

        /**
         * Generate a video background for hero section
         */
        async generateHeroVideo(businessContext, options = {}) {
            const prompt = this.buildHeroPrompt(businessContext);
            return this.startVideoGeneration(prompt, {
                ...options,
                video_type: 'hero_background',
                model: options.model || 'sora-2-pro',
                seconds: options.seconds || '8',
                size: '1280x720'
            });
        }

        /**
         * Generate a product showcase video
         */
        async generateProductVideo(productName, productDescription, options = {}) {
            const prompt = this.buildProductPrompt(productName, productDescription);
            return this.startVideoGeneration(prompt, {
                ...options,
                video_type: 'product_showcase',
                model: options.model || 'sora-2-pro',
                seconds: options.seconds || '8',
                size: '1280x720'
            });
        }

        /**
         * Generate 360° spin video from a single product image
         */
        async generate360FromImage(imageUrl, productName, options = {}) {
            return new Promise((resolve, reject) => {
                const formData = new FormData();
                formData.append('action', 'vmo_generate_360_product_video');
                formData.append('security', this.nonce);
                formData.append('image_url', imageUrl);
                formData.append('product_name', productName);
                formData.append('model', options.model || 'sora-2-pro');

                fetch(this.ajaxUrl, {
                    method: 'POST',
                    body: formData,
                    credentials: 'same-origin'
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        // Start polling for completion
                        this.trackJob(data.data.video_id, {
                            type: '360_spin',
                            productName,
                            onComplete: resolve,
                            onError: reject
                        });
                    } else {
                        reject(new Error(data.data?.message || 'Generation failed'));
                    }
                })
                .catch(reject);
            });
        }

        /**
         * Create 360° spin viewer from multiple product images (no AI needed)
         */
        async create360FromImages(images, containerSelector, options = {}) {
            return new Promise((resolve, reject) => {
                const formData = new FormData();
                formData.append('action', 'vmo_create_spin_video_from_images');
                formData.append('security', this.nonce);
                
                images.forEach((img, i) => {
                    formData.append(`images[${i}]`, img);
                });

                fetch(this.ajaxUrl, {
                    method: 'POST',
                    body: formData,
                    credentials: 'same-origin'
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        // Initialize the 360 viewer
                        const container = document.querySelector(containerSelector);
                        if (container && window.VMO360SpinViewer) {
                            const viewer = new VMO360SpinViewer(container, {
                                frames: data.data.frames,
                                ...data.data.config,
                                ...options
                            });
                            resolve({ viewer, config: data.data });
                        } else {
                            resolve(data.data);
                        }
                    } else {
                        reject(new Error(data.data?.message || 'Failed to create spin viewer'));
                    }
                })
                .catch(reject);
            });
        }

        /**
         * Start video generation
         */
        async startVideoGeneration(prompt, options = {}) {
            return new Promise((resolve, reject) => {
                const formData = new FormData();
                formData.append('action', 'vmo_generate_video');
                formData.append('security', this.nonce);
                formData.append('prompt', prompt);
                formData.append('model', options.model || 'sora-2');
                formData.append('seconds', options.seconds || '8');
                formData.append('size', options.size || '1280x720');
                formData.append('video_type', options.video_type || 'custom');

                fetch(this.ajaxUrl, {
                    method: 'POST',
                    body: formData,
                    credentials: 'same-origin'
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        this.trackJob(data.data.video_id, {
                            type: options.video_type,
                            prompt,
                            onComplete: resolve,
                            onError: reject
                        });
                    } else {
                        reject(new Error(data.data?.message || 'Generation failed'));
                    }
                })
                .catch(reject);
            });
        }

        /**
         * Track a video generation job
         */
        trackJob(videoId, jobInfo) {
            this.activeJobs.set(videoId, {
                ...jobInfo,
                startTime: Date.now(),
                status: 'queued'
            });

            this.pollJobStatus(videoId);
        }

        /**
         * Poll for job status
         */
        async pollJobStatus(videoId) {
            const job = this.activeJobs.get(videoId);
            if (!job) return;

            try {
                const formData = new FormData();
                formData.append('action', 'vmo_check_video_status');
                formData.append('security', this.nonce);
                formData.append('video_id', videoId);

                const response = await fetch(this.ajaxUrl, {
                    method: 'POST',
                    body: formData,
                    credentials: 'same-origin'
                });

                const data = await response.json();

                if (!data.success) {
                    throw new Error(data.data?.message || 'Status check failed');
                }

                const status = data.data.status;
                const progress = data.data.progress || 0;

                // Update job status
                job.status = status;
                job.progress = progress;

                // Emit progress event
                this.emitProgress(videoId, status, progress);

                if (status === 'completed') {
                    // Download the video
                    await this.downloadCompletedVideo(videoId, job);
                } else if (status === 'failed') {
                    job.onError(new Error(data.data.error?.message || 'Video generation failed'));
                    this.activeJobs.delete(videoId);
                } else {
                    // Continue polling
                    setTimeout(() => this.pollJobStatus(videoId), this.pollInterval);
                }
            } catch (error) {
                job.onError(error);
                this.activeJobs.delete(videoId);
            }
        }

        /**
         * Download completed video
         */
        async downloadCompletedVideo(videoId, job) {
            try {
                const formData = new FormData();
                formData.append('action', 'vmo_download_video');
                formData.append('security', this.nonce);
                formData.append('video_id', videoId);
                formData.append('video_type', job.type);
                formData.append('prompt', job.prompt || '');
                formData.append('title', job.title || `VMO ${job.type} Video`);

                const response = await fetch(this.ajaxUrl, {
                    method: 'POST',
                    body: formData,
                    credentials: 'same-origin'
                });

                const data = await response.json();

                if (data.success) {
                    job.onComplete({
                        videoId,
                        url: data.data.url,
                        attachmentId: data.data.attachment_id,
                        type: job.type
                    });
                } else {
                    throw new Error(data.data?.message || 'Download failed');
                }
            } catch (error) {
                job.onError(error);
            }

            this.activeJobs.delete(videoId);
        }

        /**
         * Emit progress event
         */
        emitProgress(videoId, status, progress) {
            const event = new CustomEvent('vmo:video:progress', {
                detail: { videoId, status, progress }
            });
            document.dispatchEvent(event);
        }

        /**
         * Build hero video prompt
         */
        buildHeroPrompt(context) {
            const industry = context.industry || 'business';
            const personality = context.brand_personality || 'modern and professional';
            const colors = context.colors || '';
            
            let prompt = `Cinematic hero background video for a ${industry} website. `;
            prompt += `Brand style: ${personality}. `;
            prompt += `Smooth, subtle motion perfect for a website hero section. `;
            
            if (colors) {
                prompt += `Color palette hints: ${colors}. `;
            }
            
            prompt += `No text, no people's faces, no logos. `;
            prompt += `Elegant lighting, shallow depth of field, professional color grading. `;
            prompt += `Ambient movement that doesn't distract from overlaid text.`;
            
            return prompt;
        }

        /**
         * Build product video prompt
         */
        buildProductPrompt(name, description) {
            let prompt = `Professional product showcase video for: ${name}. `;
            
            if (description) {
                prompt += `Product: ${description}. `;
            }
            
            prompt += `Elegant presentation on a clean, minimalist background. `;
            prompt += `Smooth camera movement around the product. `;
            prompt += `Soft studio lighting, subtle shadows, premium feel. `;
            prompt += `No text, no watermarks. `;
            prompt += `E-commerce quality, high-end product photography style in motion.`;
            
            return prompt;
        }

        /**
         * Get token cost estimate for video
         */
        getTokenCost(model = 'sora-2', seconds = '8') {
            const costs = {
                'sora-2': { '4': 2000, '8': 3500, '12': 5000 },
                'sora-2-pro': { '4': 4000, '8': 7000, '12': 10000 }
            };
            return costs[model]?.[seconds] || 3500;
        }

        /**
         * Check if product type benefits from 360° view
         */
        productNeeds360View(businessType, productType = '') {
            const physicalProducts = [
                'shoe', 'footwear', 'sneaker',
                'cosmetic', 'makeup', 'beauty',
                'jewelry', 'watch',
                'bag', 'handbag', 'purse',
                'furniture', 'chair', 'table',
                'electronics', 'phone', 'laptop',
                'clothing', 'apparel', 'fashion',
                'art', 'sculpture', 'collectible',
                'toy', 'appliance', 'cookware',
                'sports', 'equipment', 'gear',
                'ecommerce', 'shop', 'store',
                'dropshipping', 'retail'
            ];

            const serviceBusinesses = [
                'videographer', 'photographer',
                'consultant', 'lawyer', 'accountant',
                'doctor', 'dentist', 'therapist',
                'coach', 'agency', 'marketing',
                'cleaning', 'lawn', 'handyman',
                'restaurant', 'cafe', 'catering',
                'gym', 'fitness', 'yoga',
                'real estate', 'insurance',
                'education', 'tutoring',
                'non-profit', 'church'
            ];

            const checkText = (businessType + ' ' + productType).toLowerCase();

            // Services don't need 360°
            for (const service of serviceBusinesses) {
                if (checkText.includes(service)) return false;
            }

            // Physical products benefit from 360°
            for (const product of physicalProducts) {
                if (checkText.includes(product)) return true;
            }

            // Default based on keywords
            return checkText.includes('product') || checkText.includes('sell');
        }
    }

    // Create and expose instance
    window.VMOVideoGenerator = new VMOVideoGenerator();

    // Helper function for easy access
    window.vmoGenerateVideo = async function(type, context, options = {}) {
        const generator = window.VMOVideoGenerator;
        
        switch (type) {
            case 'hero':
                return generator.generateHeroVideo(context, options);
            case 'product':
                return generator.generateProductVideo(context.name, context.description, options);
            case '360-image':
                return generator.generate360FromImage(context.imageUrl, context.name, options);
            case '360-images':
                return generator.create360FromImages(context.images, context.container, options);
            default:
                return generator.startVideoGeneration(context.prompt, options);
        }
    };

})();
