// ========================================
// SMART ANALYSIS LAYER - Analyse intelligente avant amélioration
// Responsabilité: Analyser contenu et identifier améliorations précises nécessaires
// LLM: GPT-4o-mini (objectivité, température basse)
// Architecture: Phase 1 de SelectiveSmartTouch (Analyse → Amélioration ciblée)
// ========================================

const { callLLM } = require('../LLMManager');
const { logSh } = require('../ErrorReporting');
const { tracer } = require('../trace');

/**
 * SMART ANALYSIS LAYER
 * Analyse objective du contenu pour identifier améliorations précises
 */
class SmartAnalysisLayer {
  constructor() {
    this.name = 'SmartAnalysis';
    this.defaultLLM = 'gpt-4o-mini';
  }

  /**
   * ANALYSE COMPLÈTE D'UN ÉLÉMENT
   * @param {string} content - Contenu à analyser
   * @param {object} context - Contexte (mc0, personality, llmProvider, etc.)
   * @returns {object} - Analyse JSON structurée
   */
  async analyzeElement(content, context = {}) {
    return await tracer.run('SmartAnalysis.analyzeElement()', async () => {
      const { mc0, personality, llmProvider } = context;

      // ✅ Utiliser LLM fourni dans context, sinon fallback sur defaultLLM
      const llmToUse = llmProvider || this.defaultLLM;

      await tracer.annotate({
        smartAnalysis: true,
        contentLength: content.length,
        hasMc0: !!mc0,
        hasPersonality: !!personality,
        llmProvider: llmToUse
      });

      const startTime = Date.now();
      logSh(`🔍 SMART ANALYSIS: Analyse d'un élément (${content.length} chars) avec ${llmToUse}`, 'DEBUG');

      try {
        const prompt = this.createAnalysisPrompt(content, context);

        const response = await callLLM(llmToUse, prompt, {
          temperature: 0.2,  // Basse température = objectivité
          maxTokens: 1500
        });

        // Parser JSON de l'analyse
        const analysis = this.parseAnalysisResponse(response);

        const duration = Date.now() - startTime;
        logSh(`✅ Analyse terminée: ${analysis.improvements.length} améliorations identifiées (${duration}ms)`, 'DEBUG');

        await tracer.event('Smart Analysis terminée', {
          duration,
          improvementsCount: analysis.improvements.length,
          needsImprovement: analysis.overallScore < 0.7
        });

        return analysis;

      } catch (error) {
        const duration = Date.now() - startTime;
        logSh(`❌ SMART ANALYSIS ÉCHOUÉE (${duration}ms): ${error.message}`, 'ERROR');

        // Fallback: analyse basique algorithmique
        return this.fallbackAnalysis(content, context);
      }
    }, { contentLength: content.length, context });
  }

  /**
   * ANALYSE BATCH DE PLUSIEURS ÉLÉMENTS
   */
  async analyzeBatch(contentMap, context = {}) {
    return await tracer.run('SmartAnalysis.analyzeBatch()', async () => {
      const startTime = Date.now();
      const results = {};

      logSh(`🔍 SMART ANALYSIS BATCH: ${Object.keys(contentMap).length} éléments`, 'INFO');

      for (const [tag, content] of Object.entries(contentMap)) {
        try {
          results[tag] = await this.analyzeElement(content, context);
          logSh(`   ✅ [${tag}]: ${results[tag].improvements.length} améliorations`, 'DEBUG');
        } catch (error) {
          logSh(`   ❌ [${tag}]: Analyse échouée - ${error.message}`, 'ERROR');
          results[tag] = this.fallbackAnalysis(content, context);
        }

        // Petit délai pour éviter rate limiting
        await new Promise(resolve => setTimeout(resolve, 500));
      }

      const duration = Date.now() - startTime;
      logSh(`✅ SMART ANALYSIS BATCH terminé: ${Object.keys(results).length} éléments analysés (${duration}ms)`, 'INFO');

      return results;
    }, { elementsCount: Object.keys(contentMap).length });
  }

  /**
   * DÉTECTION CONTEXTUELLE (B2C vs B2B, niveau technique)
   * Permet d'adapter les améliorations au public cible
   */
  detectContentContext(content, personality = null) {
    logSh('🔍 Détection contexte contenu...', 'DEBUG');

    const context = {
      audience: 'unknown',        // B2C, B2B, mixed
      techLevel: 'medium',        // low, medium, high, too_high
      contentType: 'unknown',     // ecommerce, service, informative, technical
      sector: 'general'
    };

    // === DÉTECTION AUDIENCE ===
    const b2cSignals = [
      'acheter', 'votre maison', 'chez vous', 'personnalisé', 'facile',
      'simple', 'idéal pour vous', 'particulier', 'famille', 'clients'
    ];
    const b2bSignals = [
      'entreprise', 'professionnel', 'solution industrielle',
      'cahier des charges', 'conformité', 'optimisation des processus'
    ];

    const b2cCount = b2cSignals.filter(s => content.toLowerCase().includes(s)).length;
    const b2bCount = b2bSignals.filter(s => content.toLowerCase().includes(s)).length;

    if (b2cCount > b2bCount && b2cCount > 2) context.audience = 'B2C';
    else if (b2bCount > b2cCount && b2bCount > 2) context.audience = 'B2B';
    else if (b2cCount > 0 && b2bCount > 0) context.audience = 'mixed';

    // === DÉTECTION NIVEAU TECHNIQUE ===
    const jargonWords = [
      'norme', 'coefficient', 'résistance', 'ISO', 'ASTM', 'certifié',
      'EN ', 'DIN', 'conforme', 'spécification', 'standard', 'référence'
    ];
    const technicalSpecs = (content.match(/\d+\s*(mm|cm|kg|°C|%|watt|lumen|J\/cm²|K⁻¹)/g) || []).length;
    const jargonCount = jargonWords.filter(w => content.includes(w)).length;

    if (jargonCount > 5 || technicalSpecs > 8) {
      context.techLevel = 'too_high';
    } else if (jargonCount > 2 || technicalSpecs > 4) {
      context.techLevel = 'high';
    } else if (jargonCount === 0 && technicalSpecs < 2) {
      context.techLevel = 'low';
    }

    // === DÉTECTION TYPE CONTENU ===
    const ecommerceKeywords = ['prix', 'acheter', 'commander', 'livraison', 'stock', 'produit'];
    const serviceKeywords = ['prestation', 'accompagnement', 'conseil', 'expertise', 'service'];

    if (ecommerceKeywords.filter(k => content.toLowerCase().includes(k)).length > 2) {
      context.contentType = 'ecommerce';
    } else if (serviceKeywords.filter(k => content.toLowerCase().includes(k)).length > 2) {
      context.contentType = 'service';
    } else if (jargonCount > 3) {
      context.contentType = 'technical';
    } else {
      context.contentType = 'informative';
    }

    // === INTÉGRATION DONNÉES PERSONALITY ===
    if (personality) {
      if (personality.targetAudience?.toLowerCase().includes('grand public')) {
        context.audience = 'B2C';
      }
      if (personality.secteur) {
        context.sector = personality.secteur;
      }
      if (personality.tone?.includes('accessible') || personality.tone?.includes('simple')) {
        context.preferSimple = true;
      }
    }

    logSh(`✅ Contexte détecté: audience=${context.audience}, techLevel=${context.techLevel}, type=${context.contentType}`, 'DEBUG');

    return context;
  }

  /**
   * ANALYSE PAR SEGMENTS (découpe + score individuel)
   * Permet de sélectionner seulement les segments les plus faibles
   */
  analyzeBySegments(content, context = {}) {
    logSh('🔍 Analyse par segments...', 'DEBUG');

    // Découper en phrases (simpliste mais efficace)
    const sentences = content.split(/(?<=[.!?])\s+/).filter(s => s.trim().length > 10);

    const segments = sentences.map((sentence, index) => {
      // Score algorithmique rapide de chaque phrase
      const wordCount = sentence.split(/\s+/).length;
      const hasNumbers = /\d+/.test(sentence);
      const genericWords = ['nos solutions', 'notre expertise', 'qualité', 'service'].filter(w => sentence.toLowerCase().includes(w)).length;
      const jargonWords = ['norme', 'coefficient', 'ISO', 'certifié'].filter(w => sentence.includes(w)).length;

      let score = 0.5; // Score de base

      // Pénalités
      if (wordCount > 30) score -= 0.2;  // Trop longue
      if (genericWords > 0) score -= 0.15 * genericWords;  // Vocabulaire générique
      if (jargonWords > 1) score -= 0.1 * jargonWords;  // Trop de jargon

      // Bonus
      if (hasNumbers && wordCount < 20) score += 0.1;  // Concise avec données

      score = Math.max(0.0, Math.min(1.0, score));  // Clamp entre 0 et 1

      return {
        index,
        content: sentence,
        score,
        wordCount,
        issues: [
          wordCount > 30 ? 'trop_longue' : null,
          genericWords > 0 ? 'vocabulaire_générique' : null,
          jargonWords > 1 ? 'trop_technique' : null
        ].filter(Boolean)
      };
    });

    logSh(`✅ ${segments.length} segments analysés`, 'DEBUG');

    return segments;
  }

  /**
   * SÉLECTION DES X% SEGMENTS LES PLUS FAIBLES
   * Retourne indices des segments à améliorer
   */
  selectWeakestSegments(segments, percentage = 0.1) {
    // Trier par score croissant (plus faibles d'abord)
    const sortedSegments = [...segments].sort((a, b) => a.score - b.score);

    // Calculer combien de segments à prendre
    const countToSelect = Math.max(1, Math.ceil(segments.length * percentage));

    // Prendre les N segments les plus faibles
    const selectedSegments = sortedSegments.slice(0, countToSelect);

    logSh(`📊 Sélection: ${selectedSegments.length}/${segments.length} segments les plus faibles (${(percentage * 100).toFixed(0)}%)`, 'INFO');

    // Retourner dans l'ordre original (par index)
    return selectedSegments.sort((a, b) => a.index - b.index);
  }

  /**
   * CRÉER PROMPT D'ANALYSE (générique, multi-secteur)
   */
  createAnalysisPrompt(content, context) {
    const { mc0, personality } = context;

    return `MISSION: Analyse OBJECTIVE de ce contenu et identifie les améliorations précises nécessaires.

CONTENU À ANALYSER:
"${content}"

${mc0 ? `CONTEXTE SUJET: ${mc0}` : 'CONTEXTE: Générique'}
${personality ? `PERSONNALITÉ CIBLE: ${personality.nom} (${personality.style})` : ''}

ANALYSE CES DIMENSIONS:

1. DIMENSION TECHNIQUE:
   - Manque-t-il des informations factuelles concrètes ?
   - Le contenu est-il trop générique ou vague ?
   - Y a-t-il besoin de données chiffrées, dimensions, spécifications ?

2. DIMENSION STYLE:
   - Le ton est-il cohérent ?
   ${personality ? `- Le style correspond-il à "${personality.style}" ?` : '- Le style est-il professionnel ?'}
   - Y a-t-il des expressions trop génériques ("nos solutions", "notre expertise") ?

3. DIMENSION LISIBILITÉ:
   - Les phrases sont-elles trop longues ou complexes ?
   - Les connecteurs sont-ils répétitifs ?
   - La structure est-elle fluide ?

4. DIMENSION VOCABULAIRE:
   - Mots génériques à remplacer par termes spécifiques ?
   - Vocabulaire adapté au sujet ?

IMPORTANT: Sois OBJECTIF et SÉLECTIF. Ne liste QUE les améliorations réellement nécessaires.
Si le contenu est déjà bon sur une dimension, indique "needed: false" pour cette dimension.

RETOURNE UN JSON (et UNIQUEMENT du JSON valide):
{
  "technical": {
    "needed": true/false,
    "score": 0.0-1.0,
    "missing": ["élément précis manquant 1", "élément précis manquant 2"],
    "issues": ["problème identifié"]
  },
  "style": {
    "needed": true/false,
    "score": 0.0-1.0,
    "toneIssues": ["problème de ton"],
    "genericPhrases": ["expression générique à personnaliser"]
  },
  "readability": {
    "needed": true/false,
    "score": 0.0-1.0,
    "complexSentences": [numéro_ligne],
    "repetitiveConnectors": ["connecteur répété"]
  },
  "vocabulary": {
    "needed": true/false,
    "score": 0.0-1.0,
    "genericWords": ["mot générique"],
    "suggestions": ["terme spécifique suggéré"]
  },
  "improvements": [
    "Amélioration précise 1",
    "Amélioration précise 2"
  ],
  "overallScore": 0.0-1.0
}`;
  }

  /**
   * PARSER RÉPONSE JSON DE L'ANALYSE
   */
  parseAnalysisResponse(response) {
    try {
      // Nettoyer la réponse (supprimer markdown, etc.)
      let cleanResponse = response.trim();

      // Supprimer balises markdown JSON
      cleanResponse = cleanResponse.replace(/```json\s*/gi, '');
      cleanResponse = cleanResponse.replace(/```\s*/g, '');

      // Parser JSON
      const analysis = JSON.parse(cleanResponse);

      // Valider structure
      if (!analysis.technical || !analysis.style || !analysis.readability || !analysis.vocabulary) {
        throw new Error('Structure JSON incomplète');
      }

      // Valider que improvements est un array
      if (!Array.isArray(analysis.improvements)) {
        analysis.improvements = [];
      }

      return analysis;

    } catch (error) {
      logSh(`⚠️ Parsing JSON échoué: ${error.message}, tentative de récupération...`, 'WARNING');

      // Tentative d'extraction partielle
      try {
        const jsonMatch = response.match(/\{[\s\S]*\}/);
        if (jsonMatch) {
          return JSON.parse(jsonMatch[0]);
        }
      } catch (e) {
        // Ignore
      }

      throw new Error(`Impossible de parser l'analyse JSON: ${error.message}`);
    }
  }

  /**
   * ANALYSE FALLBACK ALGORITHMIQUE (si LLM échoue)
   */
  fallbackAnalysis(content, context) {
    logSh(`🔄 Fallback: Analyse algorithmique de base`, 'DEBUG');

    const wordCount = content.split(/\s+/).length;
    const sentenceCount = content.split(/[.!?]+/).filter(s => s.trim().length > 5).length;
    const avgSentenceLength = wordCount / Math.max(sentenceCount, 1);

    // Analyse basique
    const genericWords = ['nos solutions', 'notre expertise', 'qualité', 'service', 'professionnel'];
    const foundGeneric = genericWords.filter(word => content.toLowerCase().includes(word));

    const improvements = [];
    let technicalScore = 0.5;
    let styleScore = 0.5;
    let readabilityScore = 0.5;

    // Détection phrases trop longues
    if (avgSentenceLength > 25) {
      improvements.push('Raccourcir les phrases trop longues (> 25 mots)');
      readabilityScore = 0.4;
    }

    // Détection vocabulaire générique
    if (foundGeneric.length > 2) {
      improvements.push(`Remplacer expressions génériques: ${foundGeneric.join(', ')}`);
      styleScore = 0.4;
    }

    // Détection manque de données concrètes
    const hasNumbers = /\d+/.test(content);
    if (!hasNumbers && wordCount > 50) {
      improvements.push('Ajouter données concrètes (chiffres, dimensions, pourcentages)');
      technicalScore = 0.4;
    }

    return {
      technical: {
        needed: technicalScore < 0.6,
        score: technicalScore,
        missing: hasNumbers ? [] : ['données chiffrées'],
        issues: []
      },
      style: {
        needed: styleScore < 0.6,
        score: styleScore,
        toneIssues: [],
        genericPhrases: foundGeneric
      },
      readability: {
        needed: readabilityScore < 0.6,
        score: readabilityScore,
        complexSentences: avgSentenceLength > 25 ? [1] : [],
        repetitiveConnectors: []
      },
      vocabulary: {
        needed: foundGeneric.length > 0,
        score: foundGeneric.length > 2 ? 0.3 : 0.6,
        genericWords: foundGeneric,
        suggestions: []
      },
      improvements,
      overallScore: (technicalScore + styleScore + readabilityScore) / 3,
      fallbackUsed: true
    };
  }

  /**
   * RÉSUMER ANALYSES BATCH
   */
  summarizeBatchAnalysis(analysisResults) {
    const summary = {
      totalElements: Object.keys(analysisResults).length,
      needsImprovement: 0,
      averageScore: 0,
      commonIssues: {
        technical: 0,
        style: 0,
        readability: 0,
        vocabulary: 0
      },
      totalImprovements: 0
    };

    let totalScore = 0;

    Object.values(analysisResults).forEach(analysis => {
      totalScore += analysis.overallScore;

      if (analysis.overallScore < 0.7) {
        summary.needsImprovement++;
      }

      if (analysis.technical.needed) summary.commonIssues.technical++;
      if (analysis.style.needed) summary.commonIssues.style++;
      if (analysis.readability.needed) summary.commonIssues.readability++;
      if (analysis.vocabulary.needed) summary.commonIssues.vocabulary++;

      summary.totalImprovements += analysis.improvements.length;
    });

    summary.averageScore = totalScore / summary.totalElements;

    return summary;
  }
}

module.exports = { SmartAnalysisLayer };
