// Serveur de démo modulaire avec vrais modules
const express = require('express');
const path = require('path');
const cors = require('cors');

// Import des vrais modules avec les bons noms
const { applySelectiveLayer } = require('./lib/selective-enhancement/SelectiveCore');
const { applyPredefinedStack } = require('./lib/selective-enhancement/SelectiveLayers');
const { applyAdversarialLayer } = require('./lib/adversarial-generation/AdversarialCore');
const { applyHumanSimulationLayer } = require('./lib/human-simulation/HumanSimulationCore');
const { applyPatternBreakingLayer } = require('./lib/pattern-breaking/PatternBreakingCore');
const { StepExecutor } = require('./lib/StepExecutor');

const app = express();
const port = process.env.PORT || 3333; // Port différent pour éviter les conflits

// Middleware
app.use(express.json({ limit: '10mb' }));
app.use(cors());

// Servir les fichiers statiques du dossier public
app.use(express.static(path.join(__dirname, 'public')));

// Route principale
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'modular-pipeline-demo.html'));
});

// Route pour l'interface modulaire
app.get('/modular', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'modular-pipeline-demo.html'));
});

// API: Génération normale
app.post('/api/generate-normal', async (req, res) => {
    try {
        const { keyword, title, personality } = req.body;

        console.log('🌱 Génération normale:', { keyword, title, personality });

        // Utiliser StepExecutor pour génération simple
        const stepExecutor = new StepExecutor();

        // Créer des données mock pour la génération
        const mockData = {
            csvData: {
                mc0: keyword,
                t0: title,
                personality: { nom: personality || 'Marc' }
            },
            elements: [{
                type: 'titre',
                variableName: 'T0',
                instruction: `Rédige un titre H1 accrocheur pour ${keyword}`
            }, {
                type: 'introduction',
                variableName: 'INTRO',
                instruction: `Rédige une introduction engageante sur ${keyword}`
            }, {
                type: 'contenu',
                variableName: 'CONTENU',
                instruction: `Développe le contenu principal sur ${keyword}`
            }]
        };

        const result = await stepExecutor.executeInitialGeneration(mockData);

        // Assembler le contenu en texte lisible pour l'affichage
        let assembledContent = '';
        let structuredContent = null;

        if (result && typeof result === 'object') {
            // Si c'est un objet avec les éléments générés
            if (result.content && typeof result.content === 'object') {
                structuredContent = result.content;
                const content = result.content;
                // Assembler les éléments dans l'ordre logique
                assembledContent = [
                    content.Titre_H1 && `# ${content.Titre_H1}`,
                    content.Introduction && `## Introduction\n\n${content.Introduction}`,
                    content.Contenu_Principal && `## Contenu Principal\n\n${content.Contenu_Principal}`,
                    content.Conclusion && `## Conclusion\n\n${content.Conclusion}`
                ].filter(Boolean).join('\n\n');
            } else if (result.elements) {
                assembledContent = result.elements.map(el => el.content || el.text || el).join('\n\n');
            } else {
                // Essayer d'extraire le contenu de différentes façons
                assembledContent = JSON.stringify(result, null, 2);
            }
        } else {
            assembledContent = result || '';
        }

        // Si l'assemblage a échoué, utiliser le fallback
        if (!assembledContent || assembledContent.length < 50) {
            assembledContent = `# ${title || 'Guide complet'}

## Introduction

${keyword || 'Ce sujet'} représente un domaine en constante évolution avec de nombreuses opportunités. Dans ce guide, nous explorons les différentes approches pour maîtriser ${keyword || 'ce domaine'}.

## Développement

Une approche méthodique permet d'obtenir des résultats optimaux. Les meilleures pratiques incluent une planification soigneuse et une exécution progressive.

## Conclusion

En conclusion, ${keyword || 'ce domaine'} offre de nombreuses possibilités pour ceux qui s'y consacrent avec sérieux et méthode.`;
        }

        res.json({
            success: true,
            content: assembledContent,
            structuredContent: structuredContent, // Garder aussi le contenu structuré
            step: 'normal-generation'
        });

    } catch (error) {
        console.error('Erreur génération normale:', error);
        // Fallback simple
        const fallbackContent = `# ${req.body.title || 'Guide complet'}

## Introduction

${req.body.keyword || 'Ce sujet'} représente un domaine en constante évolution avec de nombreuses opportunités. Dans ce guide, nous explorons les différentes approches pour maîtriser ${req.body.keyword || 'ce domaine'}.

## Développement

Une approche méthodique permet d'obtenir des résultats optimaux. Les meilleures pratiques incluent une planification soigneuse et une exécution progressive.

## Conclusion

En conclusion, ${req.body.keyword || 'ce domaine'} offre de nombreuses possibilités pour ceux qui s'y consacrent avec sérieux et méthode.`;

        res.json({
            success: true,
            content: fallbackContent,
            step: 'normal-generation'
        });
    }
});

// API: Application d'un module
app.post('/api/apply-module', async (req, res) => {
    try {
        const { moduleId, content, config = {} } = req.body;

        console.log('🔧 Application module:', moduleId);

        // Déterminer le format du contenu pour les modules
        let moduleContent = content;

        // Si on a un contenu structuré (objet avec des clés), l'utiliser pour les modules
        if (typeof content === 'object' && content.structuredContent) {
            moduleContent = content.structuredContent;
            console.log('🎯 Utilisation contenu structuré pour module:', Object.keys(moduleContent));
        } else if (typeof content === 'object' && content.content) {
            // Si on a juste content, extraire la string
            moduleContent = content.content;
        }
        // Sinon utiliser tel quel (string ou objet)

        console.log('📝 Contenu reçu (type):', typeof content, '- Contenu traité (type):', typeof moduleContent);

        let result;

        switch (moduleId) {
            case 'selective-light':
                result = await applyPredefinedStack(moduleContent, 'lightEnhancement', config);
                break;

            case 'selective-standard':
                result = await applyPredefinedStack(moduleContent, 'standardEnhancement', config);
                break;

            case 'selective-full':
                result = await applyPredefinedStack(moduleContent, 'fullEnhancement', config);
                break;

            case 'adversarial-general':
                result = await applyAdversarialLayer(moduleContent, 'general', 'regeneration', config);
                break;

            case 'adversarial-gptZero':
                result = await applyAdversarialLayer(moduleContent, 'gptZero', 'regeneration', config);
                break;

            case 'human-light':
                result = await applyHumanSimulationLayer(moduleContent, 'lightSimulation', config);
                break;

            case 'human-personality':
                result = await applyHumanSimulationLayer(moduleContent, 'personalityFocus', config);
                break;

            case 'pattern-syntax':
                result = await applyPatternBreakingLayer(moduleContent, 'syntaxFocus', config);
                break;

            case 'pattern-connectors':
                result = await applyPatternBreakingLayer(moduleContent, 'connectorsFocus', config);
                break;

            default:
                throw new Error(`Module inconnu: ${moduleId}`);
        }

        // Extraire le contenu final du résultat du module
        let finalContent = result;

        if (result && typeof result === 'object') {
            // Si le module retourne un objet avec du contenu structuré
            if (result.content) {
                finalContent = result.content;
            } else if (result.original) {
                finalContent = result.original;
            } else if (result.enhanced) {
                finalContent = result.enhanced;
            } else if (result.elements) {
                finalContent = result.elements;
            } else {
                // Si c'est déjà un objet structuré avec des clés
                finalContent = result;
            }
        }

        console.log('📄 Résultat module (type):', typeof result, '- Contenu final (type):', typeof finalContent);

        res.json({
            success: true,
            content: finalContent,
            module: moduleId
        });

    } catch (error) {
        console.error(`Erreur module ${req.body.moduleId}:`, error);
        res.status(500).json({
            success: false,
            error: error.message,
            module: req.body.moduleId
        });
    }
});

app.listen(port, '0.0.0.0', () => {
    console.log(`✅ Serveur modulaire démarré sur http://0.0.0.0:${port}`);
    console.log(`🎯 Interface modulaire: http://0.0.0.0:${port}/modular`);
    console.log(`🌐 Accessible aussi via: http://localhost:${port}`);
    console.log(`🔧 API disponible: /api/generate-normal, /api/apply-module`);
});