// === CONTENT FACTORY - GÉNÉRATEUR UNIVERSEL DE CONTENU ===

class ContentFactory {
    constructor() {
        this.parsers = new Map();
        this.generators = new Map();
        this.templates = new Map();
        this.mediaProcessor = new MediaProcessor();
        this.validator = new ContentValidator();
        
        this.initializeParsers();
        this.initializeGenerators();
        this.initializeTemplates();
    }

    // === PARSERS - ANALYSE DE CONTENU BRUT ===
    
    initializeParsers() {
        // Parser pour texte libre
        this.parsers.set('text', new TextParser());
        
        // Parser pour fichiers CSV
        this.parsers.set('csv', new CSVParser());
        
        // Parser pour JSON structuré
        this.parsers.set('json', new JSONParser());
        
        // Parser pour dialogue/script
        this.parsers.set('dialogue', new DialogueParser());
        
        // Parser pour séquences/histoires
        this.parsers.set('sequence', new SequenceParser());
        
        // Parser pour média (audio/image)
        this.parsers.set('media', new MediaParser());
    }

    // === GÉNÉRATEURS - CRÉATION D'EXERCICES ===
    
    initializeGenerators() {
        // Générateur de vocabulaire
        this.generators.set('vocabulary', new VocabularyGenerator());
        
        // Générateur de phrases
        this.generators.set('sentence', new SentenceGenerator());
        
        // Générateur de dialogues
        this.generators.set('dialogue', new DialogueGenerator());
        
        // Générateur de séquences
        this.generators.set('sequence', new SequenceGenerator());
        
        // Générateur de scénarios
        this.generators.set('scenario', new ScenarioGenerator());
        
        // Générateur automatique (détection de type)
        this.generators.set('auto', new AutoGenerator());
    }

    // === TEMPLATES - MODÈLES DE CONTENU ===
    
    initializeTemplates() {
        this.templates.set('vocabulary_simple', {
            name: 'Vocabulaire Simple',
            description: 'Mots avec traduction',
            requiredFields: ['english', 'french'],
            optionalFields: ['image', 'audio', 'phonetic', 'category'],
            interactions: ['click', 'drag_drop', 'type'],
            games: ['whack-a-mole', 'memory-game']
        });

        this.templates.set('dialogue_conversation', {
            name: 'Dialogue Conversationnel',
            description: 'Conversation entre personnages',
            requiredFields: ['speakers', 'conversation'],
            optionalFields: ['scenario', 'context', 'audio_files'],
            interactions: ['role_play', 'click', 'build_sentence'],
            games: ['story-builder']
        });

        this.templates.set('sequence_story', {
            name: 'Histoire Séquentielle',
            description: 'Étapes chronologiques',
            requiredFields: ['title', 'steps'],
            optionalFields: ['images', 'times', 'context'],
            interactions: ['chronological_order', 'drag_drop'],
            games: ['story-builder', 'memory-game']
        });

        this.templates.set('scenario_context', {
            name: 'Scénario Contextuel',
            description: 'Situation réelle complexe',
            requiredFields: ['setting', 'vocabulary', 'phrases'],
            optionalFields: ['roles', 'objectives', 'media'],
            interactions: ['simulation', 'role_play', 'click'],
            games: ['story-builder']
        });
    }

    // === MÉTHODE PRINCIPALE - CRÉATION DE CONTENU ===
    
    async createContent(input, options = {}) {
        try {
            logSh('🏭 Content Factory - Début création contenu', 'INFO');
            
            // 1. Analyser l'input
            const parsedContent = await this.parseInput(input, options);
            
            // 2. Détecter le type de contenu
            const contentType = this.detectContentType(parsedContent, options);
            
            // 3. Générer les exercices
            const exercises = await this.generateExercises(parsedContent, contentType, options);
            
            // 4. Traiter les médias
            const processedMedia = await this.processMedia(parsedContent.media || [], options);
            
            // 5. Assembler le module final
            const contentModule = this.assembleModule(exercises, processedMedia, options);
            
            // 6. Valider le résultat
            if (!this.validator.validate(contentModule)) {
                throw new Error('Contenu généré invalide');
            }
            
            logSh('✅ Content Factory - Contenu créé avec succès', 'INFO');
            return contentModule;
            
        } catch (error) {
            logSh('❌ Content Factory - Erreur:', error, 'ERROR');
            throw error;
        }
    }

    // === PARSING - ANALYSE DES INPUTS ===
    
    async parseInput(input, options) {
        const inputType = this.detectInputType(input, options);
        const parser = this.parsers.get(inputType);
        
        if (!parser) {
            throw new Error(`Parser non trouvé pour le type: ${inputType}`);
        }
        
        return await parser.parse(input, options);
    }

    detectInputType(input, options) {
        // Type explicite fourni
        if (options.inputType) {
            return options.inputType;
        }
        
        // Détection automatique
        if (typeof input === 'string') {
            if (input.includes(',') && input.includes('=')) {
                return 'csv';
            }
            if (input.includes(':') && (input.includes('A:') || input.includes('B:'))) {
                return 'dialogue';
            }
            if (input.includes('1.') || input.includes('First') || input.includes('Then')) {
                return 'sequence';
            }
            return 'text';
        }
        
        if (typeof input === 'object') {
            if (input.contentItems) return 'json';
            if (input.conversation) return 'dialogue';
            if (input.steps) return 'sequence';
        }
        
        if (Array.isArray(input)) {
            if (input[0]?.english && input[0]?.french) return 'vocabulary';
            if (input[0]?.speaker) return 'dialogue';
            if (input[0]?.order || input[0]?.step) return 'sequence';
        }
        
        return 'text'; // Fallback
    }

    detectContentType(parsedContent, options) {
        // Type explicite
        if (options.contentType) {
            return options.contentType;
        }
        
        // Détection basée sur la structure
        if (parsedContent.vocabulary && parsedContent.vocabulary.length > 0) {
            return 'vocabulary';
        }
        
        if (parsedContent.conversation || parsedContent.dialogue) {
            return 'dialogue';
        }
        
        if (parsedContent.steps || parsedContent.sequence) {
            return 'sequence';
        }
        
        if (parsedContent.scenario || parsedContent.setting) {
            return 'scenario';
        }
        
        if (parsedContent.sentences) {
            return 'sentence';
        }
        
        return 'auto'; // Génération automatique
    }

    // === GÉNÉRATION D'EXERCICES ===
    
    async generateExercises(parsedContent, contentType, options) {
        const generator = this.generators.get(contentType);
        
        if (!generator) {
            throw new Error(`Générateur non trouvé pour le type: ${contentType}`);
        }
        
        return await generator.generate(parsedContent, options);
    }

    // === ASSEMBLAGE DU MODULE ===
    
    assembleModule(exercises, media, options) {
        const moduleId = options.id || this.generateId();
        const moduleName = options.name || 'Contenu Généré';
        
        return {
            id: moduleId,
            name: moduleName,
            description: options.description || `Contenu généré automatiquement - ${new Date().toLocaleDateString()}`,
            version: "2.0",
            format: "unified",
            difficulty: options.difficulty || this.inferDifficulty(exercises),
            
            metadata: {
                totalItems: exercises.length,
                categories: this.extractCategories(exercises),
                contentTypes: this.extractContentTypes(exercises),
                generatedAt: new Date().toISOString(),
                sourceType: options.inputType || 'auto-detected'
            },
            
            config: {
                defaultInteraction: options.defaultInteraction || "click",
                supportedGames: options.supportedGames || ["whack-a-mole", "memory-game", "story-builder"],
                adaptiveEnabled: true,
                difficultyProgression: true
            },
            
            contentItems: exercises,
            
            media: media,
            
            categories: this.generateCategories(exercises),
            
            gameSettings: this.generateGameSettings(exercises, options),
            
            // Métadonnées de génération
            generation: {
                timestamp: Date.now(),
                factory_version: "1.0",
                options: options,
                stats: {
                    parsing_time: 0, // À implémenter
                    generation_time: 0,
                    total_time: 0
                }
            }
        };
    }

    // === UTILITAIRES ===
    
    generateId() {
        return 'generated_' + Date.now() + '_' + Math.random().toString(36).substr(2, 5);
    }

    inferDifficulty(exercises) {
        // Analyser la complexité des exercices
        const complexities = exercises.map(ex => {
            if (ex.type === 'vocabulary') return 1;
            if (ex.type === 'sentence') return 2;
            if (ex.type === 'dialogue') return 3;
            if (ex.type === 'scenario') return 4;
            return 2;
        });
        
        const avgComplexity = complexities.reduce((a, b) => a + b, 0) / complexities.length;
        
        if (avgComplexity <= 1.5) return 'easy';
        if (avgComplexity <= 2.5) return 'medium';
        return 'hard';
    }

    extractCategories(exercises) {
        const categories = new Set();
        exercises.forEach(ex => {
            if (ex.category) categories.add(ex.category);
            if (ex.content?.tags) {
                ex.content.tags.forEach(tag => categories.add(tag));
            }
        });
        return Array.from(categories);
    }

    extractContentTypes(exercises) {
        const types = new Set();
        exercises.forEach(ex => types.add(ex.type));
        return Array.from(types);
    }

    generateCategories(exercises) {
        const categories = {};
        const categoryGroups = this.groupByCategory(exercises);
        
        Object.keys(categoryGroups).forEach(cat => {
            categories[cat] = {
                name: this.beautifyCategory(cat),
                icon: this.getCategoryIcon(cat),
                description: `Contenu généré pour ${cat}`,
                difficulty: this.inferCategoryDifficulty(categoryGroups[cat]),
                estimatedTime: Math.ceil(categoryGroups[cat].length * 1.5)
            };
        });
        
        return categories;
    }

    generateGameSettings(exercises, options) {
        const types = this.extractContentTypes(exercises);
        
        return {
            whackAMole: {
                recommendedWords: Math.min(15, exercises.length),
                timeLimit: 60,
                maxErrors: 5,
                supportedTypes: types.filter(t => ['vocabulary', 'sentence'].includes(t))
            },
            memoryGame: {
                recommendedPairs: Math.min(8, Math.floor(exercises.length / 2)),
                timeLimit: 120,
                maxFlips: 30,
                supportedTypes: types
            },
            storyBuilder: {
                recommendedScenes: Math.min(6, exercises.length),
                timeLimit: 180,
                supportedTypes: types.filter(t => ['dialogue', 'sequence', 'scenario'].includes(t))
            },
            tempGames: {
                recommendedItems: Math.min(10, exercises.length),
                timeLimit: 90,
                supportedTypes: types
            }
        };
    }

    // === API PUBLIQUE SIMPLIFIÉE ===
    
    // Créer contenu depuis texte libre
    async fromText(text, options = {}) {
        return this.createContent(text, { ...options, inputType: 'text' });
    }
    
    // Créer contenu depuis liste vocabulaire
    async fromVocabulary(words, options = {}) {
        return this.createContent(words, { ...options, contentType: 'vocabulary' });
    }
    
    // Créer contenu depuis dialogue
    async fromDialogue(dialogue, options = {}) {
        return this.createContent(dialogue, { ...options, contentType: 'dialogue' });
    }
    
    // Créer contenu depuis séquence
    async fromSequence(steps, options = {}) {
        return this.createContent(steps, { ...options, contentType: 'sequence' });
    }
    
    // Créer contenu avec médias
    async fromMediaBundle(content, mediaFiles, options = {}) {
        return this.createContent(content, { 
            ...options, 
            media: mediaFiles,
            processMedia: true 
        });
    }

    // === TEMPLATE HELPERS ===
    
    getAvailableTemplates() {
        return Array.from(this.templates.entries()).map(([key, template]) => ({
            id: key,
            ...template
        }));
    }
    
    async fromTemplate(templateId, data, options = {}) {
        const template = this.templates.get(templateId);
        if (!template) {
            throw new Error(`Template non trouvé: ${templateId}`);
        }
        
        // Valider les données selon le template
        this.validateTemplateData(data, template);
        
        return this.createContent(data, {
            ...options,
            template: template,
            requiredFields: template.requiredFields
        });
    }

    validateTemplateData(data, template) {
        for (const field of template.requiredFields) {
            if (!data[field]) {
                throw new Error(`Champ requis manquant: ${field}`);
            }
        }
    }

    // === MÉTHODES UTILITAIRES ===
    
    groupByCategory(exercises) {
        const groups = {};
        exercises.forEach(ex => {
            const cat = ex.category || 'general';
            if (!groups[cat]) groups[cat] = [];
            groups[cat].push(ex);
        });
        return groups;
    }
    
    beautifyCategory(category) {
        const beautified = {
            'family': 'Famille',
            'animals': 'Animaux',
            'colors': 'Couleurs',
            'numbers': 'Nombres',
            'food': 'Nourriture',
            'school': 'École',
            'daily': 'Quotidien',
            'greetings': 'Salutations'
        };
        return beautified[category] || category.charAt(0).toUpperCase() + category.slice(1);
    }
    
    getCategoryIcon(category) {
        const icons = {
            'family': '👨‍👩‍👧‍👦',
            'animals': '🐱',
            'colors': '🎨',
            'numbers': '🔢',
            'food': '🍎',
            'school': '📚',
            'daily': '🌅',
            'greetings': '👋',
            'general': '📝'
        };
        return icons[category] || '📝';
    }
    
    inferCategoryDifficulty(exercises) {
        const difficulties = exercises.map(ex => {
            switch(ex.difficulty) {
                case 'easy': return 1;
                case 'medium': return 2;
                case 'hard': return 3;
                default: return 2;
            }
        });
        
        const avg = difficulties.reduce((a, b) => a + b, 0) / difficulties.length;
        
        if (avg <= 1.3) return 'easy';
        if (avg <= 2.3) return 'medium';
        return 'hard';
    }
}

// === PROCESSEUR DE MÉDIAS ===

class MediaProcessor {
    constructor() {
        this.supportedAudioFormats = ['mp3', 'wav', 'ogg'];
        this.supportedImageFormats = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
    }
    
    async processMedia(mediaFiles, options = {}) {
        const processedMedia = {
            audio: {},
            images: {},
            metadata: {
                totalFiles: mediaFiles.length,
                processedAt: new Date().toISOString()
            }
        };
        
        for (const file of mediaFiles) {
            try {
                const processed = await this.processFile(file, options);
                
                if (this.isAudioFile(file.name)) {
                    processedMedia.audio[file.id || file.name] = processed;
                } else if (this.isImageFile(file.name)) {
                    processedMedia.images[file.id || file.name] = processed;
                }
            } catch (error) {
                logSh(`Erreur traitement fichier ${file.name}:`, error, 'WARN');
            }
        }
        
        return processedMedia;
    }
    
    async processFile(file, options) {
        // Dans un environnement réel, ici on ferait :
        // - Validation du format
        // - Optimisation (compression, resize)
        // - Upload vers CDN
        // - Génération de thumbnails
        // - Extraction de métadonnées
        
        return {
            originalName: file.name,
            path: file.path || `assets/${this.getFileCategory(file.name)}/${file.name}`,
            size: file.size,
            type: file.type,
            processedAt: new Date().toISOString()
        };
    }
    
    isAudioFile(filename) {
        const ext = filename.split('.').pop().toLowerCase();
        return this.supportedAudioFormats.includes(ext);
    }
    
    isImageFile(filename) {
        const ext = filename.split('.').pop().toLowerCase();
        return this.supportedImageFormats.includes(ext);
    }
    
    getFileCategory(filename) {
        return this.isAudioFile(filename) ? 'sounds' : 'images';
    }
}

// Export global
window.ContentFactory = ContentFactory;
window.MediaProcessor = MediaProcessor;