// ========================================
// VALIDATEUR IA MULTI-CRITÈRES
// Validation intelligente du contenu généré avec scores objectifs
// ========================================

// Import correct du LLMManager
let LLMManager;
try {
  const llmModule = require('../../lib/LLMManager');
  
  // Essai direct avec callLLM
  if (llmModule && typeof llmModule.callLLM === 'function') {
    LLMManager = llmModule;
  }
  // Essai avec propriété
  else if (llmModule && llmModule.LLMManager && typeof llmModule.LLMManager.callLLM === 'function') {
    LLMManager = llmModule.LLMManager;
  }
  // Import par défaut module.exports
  else if (llmModule && llmModule.default && typeof llmModule.default.callLLM === 'function') {
    LLMManager = llmModule.default;
  }
} catch (error) {
  console.warn('LLMManager non disponible:', error.message);
}
const { logSh } = require('../../lib/ErrorReporting');

/**
 * Validateur de contenu utilisant l'IA pour évaluer la qualité
 * Scores objectifs sur 4 critères principaux
 */
class AIContentValidator {
  
  static CRITERIA = {
    QUALITY: 'quality',           // Cohérence, fluidité, pertinence
    ANTI_DETECTION: 'antiDetection',  // Variabilité, naturalité
    PERSONALITY: 'personality',   // Respect du profil sélectionné
    TECHNICAL: 'technical'        // SEO, structure, mots-clés
  };
  
  static THRESHOLDS = {
    EXCELLENT: 90,
    GOOD: 75,
    ACCEPTABLE: 60,
    POOR: 40
  };
  
  /**
   * 🧪 VALIDATION PRINCIPALE - CŒUR DU VALIDATEUR IA
   * 
   * CE QUI EST TESTÉ :
   * ✅ Appel LLM OpenAI avec prompt structuré pour évaluation objective
   * ✅ Parse JSON de la réponse IA avec validation des scores (0-100)
   * ✅ Calcul score agrégé pondéré selon importance des critères
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Construction prompt intelligent selon critères demandés
   * - Appel OpenAI avec temperature=0.1 (cohérence évaluations)
   * - Parsing JSON robuste avec fallback sur erreurs
   * - Calcul moyenne pondérée : Quality(30%) + Anti-detection(30%) + Personality(20%) + Technical(20%)
   */
  static async validateContent(content, criteria = [], context = {}) {
    try {
      logSh(`🧪 Validation IA démarrée - Critères: ${criteria.join(', ')}`, 'DEBUG');
      
      // Préparation du prompt de validation
      const prompt = this.buildValidationPrompt(content, criteria, context);
      
      // Vérification et appel LLM pour validation
      if (!LLMManager || typeof LLMManager.callLLM !== 'function') {
        throw new Error('LLMManager not available or callLLM method missing');
      }
      
      const response = await LLMManager.callLLM(
        'openai',
        prompt,
        {
          temperature: 0.1,  // Faible pour cohérence des évaluations
          max_tokens: 1500
        }
      );
      
      // Parse de la réponse
      const validationResult = this.parseValidationResponse(response, criteria);
      
      // Calcul scores agrégés
      const aggregated = this.calculateAggregatedScores(validationResult);
      
      logSh(`✅ Validation IA terminée - Score global: ${aggregated.overall}/100`, 'INFO');
      
      return {
        ...validationResult,
        ...aggregated,
        timestamp: new Date().toISOString(),
        criteria: criteria,
        context: context
      };
      
    } catch (error) {
      logSh(`❌ Erreur validation IA: ${error.message}`, 'ERROR');
      
      // Fallback avec scores neutres
      return this.getFallbackValidation(criteria, error);
    }
  }
  
  /**
   * 🔧 CONSTRUCTION PROMPT - GÉNÉRATEUR DE PROMPTS ADAPTATIFS
   * 
   * CE QUI EST TESTÉ :
   * ✅ Construction dynamique prompt selon critères sélectionnés
   * ✅ Intégration contexte (personnalité, mots-clés, longueur attendue)
   * ✅ Format JSON strict demandé à l'IA pour parsing automatique
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Template de prompt avec placeholders dynamiques
   * - Ajout conditionnel sections selon critères (Quality, Anti-detection, etc.)
   * - Troncature contenu à 2000 chars pour éviter timeout LLM
   * - Format réponse JSON strict avec scores 0-100 + feedback + confidence
   */
  static buildValidationPrompt(content, criteria, context) {
    const basePrompt = `
VALIDATION CONTENU IA - ANALYSE MULTI-CRITÈRES OBJECTIVE

Tu es un expert en évaluation de contenu généré par IA. Évalue ce contenu selon des critères objectifs et mesurables.

CONTENU À ANALYSER :
---
${content.substring(0, 2000)}${content.length > 2000 ? '...[TRONQUÉ]' : ''}
---

CONTEXTE :
${context.personality ? `- Personnalité cible : ${context.personality.nom || context.personality} (${context.personality.style || 'style non défini'})` : ''}
${context.keywords ? `- Mots-clés attendus : ${Array.isArray(context.keywords) ? context.keywords.join(', ') : context.keywords}` : ''}
${context.expectedLength ? `- Longueur attendue : ${context.expectedLength} caractères` : ''}
${context.targetAudience ? `- Audience cible : ${context.targetAudience}` : ''}

CRITÈRES D'ÉVALUATION (0-100) :`;

    let criteriaDetails = '';
    
    if (criteria.includes(this.CRITERIA.QUALITY)) {
      criteriaDetails += `

1. QUALITÉ (0-100) :
   - Cohérence du propos et logique argumentaire
   - Fluidité de lecture et transitions naturelles  
   - Pertinence par rapport au sujet
   - Richesse du vocabulaire et variété syntaxique`;
    }
    
    if (criteria.includes(this.CRITERIA.ANTI_DETECTION)) {
      criteriaDetails += `

2. ANTI-DÉTECTION (0-100) :
   - Absence de formulations typiquement IA ("comprehensive", "robust", etc.)
   - Variabilité dans les structures de phrases
   - Naturalité du ton et spontanéité
   - Présence d'imperfections humaines subtiles`;
    }
    
    if (criteria.includes(this.CRITERIA.PERSONALITY)) {
      criteriaDetails += `

3. PERSONNALITÉ (0-100) :
   - Respect du style de la personnalité cible
   - Cohérence avec le ton attendu
   - Vocabulaire approprié au profil
   - Authenticité de la voix narrative`;
    }
    
    if (criteria.includes(this.CRITERIA.TECHNICAL)) {
      criteriaDetails += `

4. TECHNIQUE/SEO (0-100) :
   - Intégration naturelle des mots-clés
   - Structure optimisée pour le référencement
   - Respect des bonnes pratiques de rédaction web
   - Équilibre lisibilité/optimisation`;
    }
    
    const responseFormat = `

RÉPONSE REQUISE - FORMAT JSON STRICT :
{
  ${criteria.map(c => `"${c}": 85`).join(',\n  ')},
  "feedback": "Analyse détaillée : points forts, points faibles, recommandations d'amélioration (max 200 mots)",
  "confidence": 0.9
}

IMPORTANT : Réponds UNIQUEMENT avec du JSON valide, sans texte avant ou après.`;
    
    return basePrompt + criteriaDetails + responseFormat;
  }
  
  /**
   * 🔍 PARSING RÉPONSE IA - EXTRACTEUR JSON ROBUSTE
   * 
   * CE QUI EST TESTÉ :
   * ✅ Extraction JSON depuis réponse LLM (même avec texte parasite)
   * ✅ Validation scores numériques dans range 0-100
   * ✅ Fallback automatique avec scores neutres sur erreurs parsing
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Regex extraction JSON : /{[\s\S]*}/ pour isoler contenu JSON
   * - Validation type number + range [0,100] pour chaque score
   * - Arrondi Math.round() des scores décimaux
   * - Clamp confidence dans [0,1] avec Math.min/Math.max
   * - Score fallback = 50 (neutre) sur erreurs
   */
  static parseValidationResponse(response, criteria) {
    try {
      // Nettoyage de la réponse
      let jsonStr = response.trim();
      
      // Extraction du JSON si emballé dans du texte
      const jsonMatch = jsonStr.match(/\{[\s\S]*\}/);
      if (jsonMatch) {
        jsonStr = jsonMatch[0];
      }
      
      const parsed = JSON.parse(jsonStr);
      
      // Validation des scores
      const validated = {};
      criteria.forEach(criterion => {
        const score = parsed[criterion];
        if (typeof score === 'number' && score >= 0 && score <= 100) {
          validated[criterion] = Math.round(score);
        } else {
          logSh(`⚠️ Score invalide pour ${criterion}: ${score}`, 'WARNING');
          validated[criterion] = 50; // Score neutre par défaut
        }
      });
      
      return {
        scores: validated,
        feedback: parsed.feedback || 'Aucun feedback fourni',
        confidence: Math.min(Math.max(parsed.confidence || 0.5, 0), 1),
        rawResponse: response
      };
      
    } catch (error) {
      logSh(`⚠️ Erreur parsing réponse validation: ${error.message}`, 'WARNING');
      
      // Scores de fallback
      const fallbackScores = {};
      criteria.forEach(c => fallbackScores[c] = 50);
      
      return {
        scores: fallbackScores,
        feedback: `Erreur parsing: ${error.message}`,
        confidence: 0.1,
        rawResponse: response
      };
    }
  }
  
  /**
   * 📊 CALCUL SCORES AGRÉGÉS - ALGORITHME DE PONDÉRATION
   * 
   * CE QUI EST TESTÉ :
   * ✅ Moyenne pondérée selon importance relative des critères
   * ✅ Classification automatique en niveaux (EXCELLENT/GOOD/ACCEPTABLE/POOR)
   * ✅ Calcul breakdown détaillé par critère
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Pondération : Quality(30%) + Anti-detection(30%) + Personality(20%) + Technical(20%)
   * - Formula : weightedSum = Σ(score[i] * weight[i]) / totalWeight
   * - Classification par seuils : ≥90=EXCELLENT, ≥75=GOOD, ≥60=ACCEPTABLE, <60=POOR
   * - Math.round() pour score entier final
   */
  static calculateAggregatedScores(validationResult) {
    const scores = validationResult.scores;
    const scoreValues = Object.values(scores);
    
    if (scoreValues.length === 0) {
      return { overall: 0, level: 'UNKNOWN' };
    }
    
    // Moyenne pondérée (qualité et anti-détection plus importants)
    const weights = {
      [this.CRITERIA.QUALITY]: 0.3,
      [this.CRITERIA.ANTI_DETECTION]: 0.3,
      [this.CRITERIA.PERSONALITY]: 0.2,
      [this.CRITERIA.TECHNICAL]: 0.2
    };
    
    let weightedSum = 0;
    let totalWeight = 0;
    
    Object.keys(scores).forEach(criterion => {
      const weight = weights[criterion] || 0.25;
      weightedSum += scores[criterion] * weight;
      totalWeight += weight;
    });
    
    const overall = Math.round(weightedSum / totalWeight);
    
    // Détermination du niveau
    let level;
    if (overall >= this.THRESHOLDS.EXCELLENT) level = 'EXCELLENT';
    else if (overall >= this.THRESHOLDS.GOOD) level = 'GOOD';
    else if (overall >= this.THRESHOLDS.ACCEPTABLE) level = 'ACCEPTABLE';
    else level = 'POOR';
    
    return {
      overall,
      level,
      breakdown: scores,
      confidence: validationResult.confidence
    };
  }
  
  /**
   * 🚨 FALLBACK VALIDATION - GESTION ROBUSTE DES ERREURS
   * 
   * CE QUI EST TESTÉ :
   * ✅ Génération scores neutres quand LLM indisponible/échec
   * ✅ Structure réponse identique pour compatibilité code appelant
   * ✅ Logging erreur pour debug + confidence=0 pour signaler échec
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Attribution score=50 (neutre) pour tous les critères demandés
   * - overall=50, level='UNKNOWN' pour indiquer validation échouée
   * - confidence=0.0 pour signaler résultat non fiable
   * - Timestamp ISO pour traçabilité
   */
  static getFallbackValidation(criteria, error) {
    const fallbackScores = {};
    criteria.forEach(c => fallbackScores[c] = 50);
    
    return {
      scores: fallbackScores,
      overall: 50,
      level: 'UNKNOWN',
      breakdown: fallbackScores,
      feedback: `Validation échouée: ${error.message}`,
      confidence: 0.0,
      error: error.message,
      timestamp: new Date().toISOString(),
      criteria: criteria
    };
  }
  
  /**
   * ⚡ VALIDATION RAPIDE - PRESET OPTIMISÉ PERFORMANCE
   * 
   * CE QUI EST TESTÉ :
   * ✅ Évaluation accélérée sur 2 critères essentiels seulement
   * ✅ Quality + Anti-detection (critères les plus discriminants)
   * ✅ Délai <3 secondes vs ~8 secondes pour validation complète
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Appel validateContent() avec criteria=[QUALITY, ANTI_DETECTION]
   * - Prompt réduit (moins de sections = moins de tokens)
   * - Même pondération mais seulement 2 critères
   * - Idéal pour validation temps réel ou batch processing
   */
  static async quickValidate(content, context = {}) {
    return this.validateContent(
      content,
      [this.CRITERIA.QUALITY, this.CRITERIA.ANTI_DETECTION],
      context
    );
  }
  
  /**
   * 🔬 VALIDATION COMPLÈTE - ANALYSE EXHAUSTIVE 4 CRITÈRES
   * 
   * CE QUI EST TESTÉ :
   * ✅ Évaluation approfondie sur TOUS les critères disponibles
   * ✅ Quality + Anti-detection + Personality + Technical/SEO
   * ✅ Maximum de précision pour validation finale avant publication
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Appel validateContent() avec Object.values(CRITERIA) = tous critères
   * - Prompt complet avec 4 sections détaillées
   * - Pondération complète 30%+30%+20%+20%
   * - Délai ~8-12 secondes pour analyse exhaustive
   */
  static async fullValidate(content, context = {}) {
    return this.validateContent(
      content,
      Object.values(this.CRITERIA),
      context
    );
  }
  
  /**
   * 🔄 COMPARAISON CONTENUS - ALGORITHME DE DIFFÉRENTIEL
   * 
   * CE QUI EST TESTÉ :
   * ✅ Validation parallèle des 2 contenus (Promise.all pour performance)
   * ✅ Calcul différences score par score pour chaque critère
   * ✅ Détermination gagnant automatique + score d'amélioration
   * 
   * ALGORITHMES EXÉCUTÉS :
   * - Double appel validateContent() en parallèle (versionA, versionB)
   * - Delta calculation : diff[criterion] = scoreB - scoreA pour chaque critère
   * - overallDiff = validation2.overall - validation1.overall
   * - Winner logic : diff>0='B', diff<0='A', diff=0='TIE'
   * - Structure comparison complète pour analyse détaillée
   */
  static async compareContent(content1, content2, criteria = [], context = {}) {
    logSh('🔄 Comparaison de deux contenus', 'DEBUG');
    
    const [validation1, validation2] = await Promise.all([
      this.validateContent(content1, criteria, { ...context, label: 'Version A' }),
      this.validateContent(content2, criteria, { ...context, label: 'Version B' })
    ]);
    
    // Calcul des différences
    const comparison = {
      versionA: validation1,
      versionB: validation2,
      differences: {},
      winner: null,
      improvement: 0
    };
    
    criteria.forEach(criterion => {
      const diff = validation2.scores[criterion] - validation1.scores[criterion];
      comparison.differences[criterion] = diff;
    });
    
    const overallDiff = validation2.overall - validation1.overall;
    comparison.improvement = overallDiff;
    comparison.winner = overallDiff > 0 ? 'B' : (overallDiff < 0 ? 'A' : 'TIE');
    
    return comparison;
  }
}

module.exports = { AIContentValidator };