// ========================================
// INITIAL GENERATION LAYER - GÉNÉRATION INITIALE MODULAIRE
// Responsabilité: Génération de contenu initial réutilisable
// LLM: Claude Sonnet-4 (précision et créativité équilibrée)
// ========================================

const { callLLM } = require('../LLMManager');
const { logSh } = require('../ErrorReporting');
const { tracer } = require('../trace');
const { chunkArray, sleep } = require('../selective-enhancement/SelectiveUtils');

/**
 * COUCHE GÉNÉRATION INITIALE MODULAIRE
 */
class InitialGenerationLayer {
  constructor() {
    this.name = 'InitialGeneration';
    this.defaultLLM = 'claude-sonnet-4-5';
    this.priority = 0; // Priorité maximale - appliqué en premier
  }

  /**
   * MAIN METHOD - Générer contenu initial
   */
  async apply(contentStructure, config = {}) {
    return await tracer.run('InitialGenerationLayer.apply()', async () => {
      const {
        llmProvider = this.defaultLLM,
        temperature = 0.7,
        csvData = null,
        context = {}
      } = config;

      await tracer.annotate({
        initialGeneration: true,
        llmProvider,
        temperature,
        elementsCount: Object.keys(contentStructure).length,
        mc0: csvData?.mc0
      });

      const startTime = Date.now();
      logSh(`🎯 INITIAL GENERATION: Génération contenu initial (${llmProvider})`, 'INFO');
      logSh(`   📊 ${Object.keys(contentStructure).length} éléments à générer`, 'INFO');

      try {
        // Créer les éléments à générer à partir de la structure
        const elementsToGenerate = this.prepareElementsForGeneration(contentStructure, csvData);
        
        // Générer en chunks pour gérer les gros contenus
        const results = {};
        const chunks = chunkArray(Object.entries(elementsToGenerate), 4); // Chunks de 4 pour Claude
        
        for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
          const chunk = chunks[chunkIndex];
          
          try {
            logSh(`   📦 Chunk génération ${chunkIndex + 1}/${chunks.length}: ${chunk.length} éléments`, 'DEBUG');
            
            const generationPrompt = this.createInitialGenerationPrompt(chunk, csvData, config);
            
            const response = await callLLM(llmProvider, generationPrompt, {
              temperature,
              maxTokens: 4000
            }, csvData?.personality);
            
            const chunkResults = this.parseInitialGenerationResponse(response, chunk);
            Object.assign(results, chunkResults);
            
            logSh(`   ✅ Chunk génération ${chunkIndex + 1}: ${Object.keys(chunkResults).length} générés`, 'DEBUG');
            
            // Délai entre chunks
            if (chunkIndex < chunks.length - 1) {
              await sleep(2000);
            }
            
          } catch (error) {
            logSh(`   ❌ Chunk génération ${chunkIndex + 1} échoué: ${error.message}`, 'ERROR');
            
            // Fallback: contenu basique
            chunk.forEach(([tag, instruction]) => {
              results[tag] = this.createFallbackContent(tag, csvData);
            });
          }
        }

        const duration = Date.now() - startTime;
        const stats = {
          generated: Object.keys(results).length,
          total: Object.keys(contentStructure).length,
          generationRate: (Object.keys(results).length / Math.max(Object.keys(contentStructure).length, 1)) * 100,
          duration,
          llmProvider,
          temperature
        };

        logSh(`✅ INITIAL GENERATION TERMINÉE: ${stats.generated}/${stats.total} générés (${duration}ms)`, 'INFO');

        await tracer.event('Initial generation appliquée', stats);

        return { content: results, stats };

      } catch (error) {
        const duration = Date.now() - startTime;
        logSh(`❌ INITIAL GENERATION ÉCHOUÉE après ${duration}ms: ${error.message}`, 'ERROR');
        throw error;
      }
    }, { contentStructure: Object.keys(contentStructure), config });
  }

  /**
   * PRÉPARER ÉLÉMENTS POUR GÉNÉRATION
   */
  prepareElementsForGeneration(contentStructure, csvData) {
    const elements = {};
    
    // Convertir la structure en instructions de génération
    Object.entries(contentStructure).forEach(([tag, placeholder]) => {
      elements[tag] = {
        type: this.detectElementType(tag),
        instruction: this.createInstructionFromPlaceholder(placeholder, csvData),
        context: csvData?.mc0 || 'contenu personnalisé'
      };
    });
    
    return elements;
  }

  /**
   * DÉTECTER TYPE D'ÉLÉMENT
   */
  detectElementType(tag) {
    const tagLower = tag.toLowerCase();

    // 🔥 FIX: Vérifier d'abord les suffixes _title vs _text pour éviter confusion
    if (tagLower.endsWith('_title')) {
      return 'titre';
    } else if (tagLower.endsWith('_text')) {
      return 'contenu';
    }

    // Legacy patterns (pour compatibilité)
    if (tagLower.includes('titre_h') || tagLower === 'titre_h1' || tagLower.startsWith('titre_')) {
      return 'titre';
    } else if (tagLower.includes('intro') || tagLower.includes('introduction')) {
      return 'introduction';
    } else if (tagLower.includes('conclusion')) {
      return 'conclusion';
    } else if (tagLower.includes('faq') || tagLower.includes('question')) {
      return 'faq';
    } else if (tagLower.startsWith('txt_') || tagLower.includes('_text')) {
      return 'contenu';
    } else {
      return 'contenu';
    }
  }

  /**
   * CRÉER INSTRUCTION À PARTIR DU PLACEHOLDER
   */
  createInstructionFromPlaceholder(placeholder, csvData) {
    // Si c'est déjà une vraie instruction, la garder
    if (typeof placeholder === 'string' && placeholder.length > 30) {
      return placeholder;
    }
    
    // Sinon, créer une instruction basique
    const mc0 = csvData?.mc0 || 'produit';
    return `Rédige un contenu professionnel et engageant sur ${mc0}`;
  }

  /**
   * CRÉER PROMPT GÉNÉRATION INITIALE
   */
  createInitialGenerationPrompt(chunk, csvData, config) {
    const personality = csvData?.personality;
    const mc0 = csvData?.mc0 || 'contenu personnalisé';
    
    let prompt = `MISSION: Génère du contenu SEO initial de haute qualité.

CONTEXTE: ${mc0} - Article optimisé SEO
${personality ? `PERSONNALITÉ: ${personality.nom} (${personality.style})` : ''}
TEMPÉRATURE: ${config.temperature || 0.7} (créativité équilibrée)

ÉLÉMENTS À GÉNÉRER:

${chunk.map(([tag, data], i) => `[${i + 1}] TAG: ${tag}
TYPE: ${data.type}
INSTRUCTION: ${data.instruction}
CONTEXTE: ${data.context}`).join('\n\n')}

CONSIGNES GÉNÉRATION:
- CRÉE du contenu original et engageant${personality ? ` avec le style ${personality.style}` : ''}
- INTÈGRE naturellement le mot-clé "${mc0}" 
- RESPECTE les bonnes pratiques SEO (mots-clés, structure)
- ADAPTE longueur selon type d'élément:
  * Titres: 8-15 mots
  * Introduction: 2-3 phrases (40-80 mots)
  * Contenu: 3-6 phrases (80-200 mots)  
  * Conclusion: 2-3 phrases (40-80 mots)
- ÉVITE contenu générique, sois spécifique et informatif
- UTILISE un ton professionnel mais accessible

VOCABULAIRE RECOMMANDÉ SELON CONTEXTE:
- Si signalétique: matériaux (dibond, aluminium), procédés (gravure, impression)
- Adapte selon le domaine du mot-clé principal

FORMAT RÉPONSE:
[1] Contenu généré pour premier élément
[2] Contenu généré pour deuxième élément
etc...

IMPORTANT: Réponse DIRECTE par les contenus générés, pas d'explication.`;

    return prompt;
  }

  /**
   * PARSER RÉPONSE GÉNÉRATION INITIALE
   */
  parseInitialGenerationResponse(response, chunk) {
    const results = {};
    const regex = /\[(\d+)\]\s*([^[]*?)(?=\n\[\d+\]|$)/gs;
    let match;
    let index = 0;
    
    while ((match = regex.exec(response)) && index < chunk.length) {
      let generatedContent = match[2].trim();
      const [tag] = chunk[index];
      
      // Nettoyer contenu généré
      generatedContent = this.cleanGeneratedContent(generatedContent);
      
      if (generatedContent && generatedContent.length > 10) {
        results[tag] = generatedContent;
        logSh(`✅ Généré [${tag}]: "${generatedContent.substring(0, 60)}..."`, 'DEBUG');
      } else {
        results[tag] = this.createFallbackContent(tag, chunk[index][1]);
        logSh(`⚠️ Fallback génération [${tag}]: contenu invalide`, 'WARNING');
      }
      
      index++;
    }
    
    // Compléter les manquants
    while (index < chunk.length) {
      const [tag, data] = chunk[index];
      results[tag] = this.createFallbackContent(tag, data);
      index++;
    }
    
    return results;
  }

  /**
   * NETTOYER CONTENU GÉNÉRÉ
   */
  cleanGeneratedContent(content) {
    if (!content) return content;
    
    // Supprimer préfixes indésirables
    content = content.replace(/^(voici\s+)?le\s+contenu\s+(généré|pour)\s*[:.]?\s*/gi, '');
    content = content.replace(/^(contenu|élément)\s+(généré|pour)\s*[:.]?\s*/gi, '');
    content = content.replace(/^(bon,?\s*)?(alors,?\s*)?/gi, '');
    
    // Nettoyer formatage
    content = content.replace(/\*\*[^*]+\*\*/g, ''); // Gras markdown
    content = content.replace(/\s{2,}/g, ' '); // Espaces multiples
    content = content.trim();
    
    return content;
  }

  /**
   * CRÉER CONTENU FALLBACK
   */
  createFallbackContent(tag, data) {
    const mc0 = data?.context || 'produit';
    const type = data?.type || 'contenu';
    
    switch (type) {
      case 'titre':
        return `${mc0.charAt(0).toUpperCase()}${mc0.slice(1)} de qualité professionnelle`;
      case 'introduction':
        return `Découvrez notre gamme complète de ${mc0}. Qualité premium et service personnalisé.`;
      case 'conclusion':
        return `Faites confiance à notre expertise pour votre ${mc0}. Contactez-nous pour plus d'informations.`;
      default:
        return `Notre ${mc0} répond à vos besoins avec des solutions adaptées et un service de qualité.`;
    }
  }
}

module.exports = { InitialGenerationLayer };