// ========================================
// WORKFLOW ENGINE - SÉQUENCES MODULAIRES CONFIGURABLES
// Responsabilité: Gestion flexible de l'ordre d'exécution des phases modulaires
// ========================================

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

// Import des modules disponibles
const { applySelectiveEnhancement } = require('../selective-enhancement/SelectiveCore');
const { applyAdversarialEnhancement } = require('../adversarial-generation/AdversarialCore');
const { applyHumanSimulation } = require('../human-simulation/HumanSimulationCore');
const { applyPatternBreaking } = require('../pattern-breaking/PatternBreakingCore');

/**
 * WORKFLOW ENGINE
 * Permet de configurer des séquences personnalisées de traitement modulaire
 */
class WorkflowEngine {
  constructor() {
    this.name = 'WorkflowEngine';
    this.predefinedSequences = new Map();
    this.customSequences = new Map();

    // Initialiser les séquences prédéfinies
    this.initializePredefinedSequences();
  }

  // ========================================
  // SÉQUENCES PRÉDÉFINIES
  // ========================================

  initializePredefinedSequences() {
    // Séquence par défaut (workflow actuel)
    this.predefinedSequences.set('default', {
      name: 'Default Workflow',
      description: 'Séquence standard: Selective → Adversarial → Human → Pattern',
      phases: [
        { type: 'selective', config: { enabled: true } },
        { type: 'adversarial', config: { enabled: true } },
        { type: 'human', config: { enabled: true } },
        { type: 'pattern', config: { enabled: true } }
      ]
    });

    // Séquence humanisée d'abord
    this.predefinedSequences.set('human-first', {
      name: 'Human-First Workflow',
      description: 'Humanisation d\'abord: Human → Pattern → Selective → Pattern',
      phases: [
        { type: 'human', config: { enabled: true } },
        { type: 'pattern', config: { enabled: true, iteration: 1 } },
        { type: 'selective', config: { enabled: true } },
        { type: 'pattern', config: { enabled: true, iteration: 2 } }
      ]
    });

    // Séquence anti-détection intensive
    this.predefinedSequences.set('stealth-intensive', {
      name: 'Stealth Intensive',
      description: 'Anti-détection max: Pattern → Adversarial → Human → Pattern → Adversarial',
      phases: [
        { type: 'pattern', config: { enabled: true, iteration: 1 } },
        { type: 'adversarial', config: { enabled: true, iteration: 1 } },
        { type: 'human', config: { enabled: true } },
        { type: 'pattern', config: { enabled: true, iteration: 2 } },
        { type: 'adversarial', config: { enabled: true, iteration: 2 } }
      ]
    });

    // Séquence qualité d'abord
    this.predefinedSequences.set('quality-first', {
      name: 'Quality-First Workflow',
      description: 'Qualité prioritaire: Selective → Human → Selective → Pattern',
      phases: [
        { type: 'selective', config: { enabled: true, iteration: 1 } },
        { type: 'human', config: { enabled: true } },
        { type: 'selective', config: { enabled: true, iteration: 2 } },
        { type: 'pattern', config: { enabled: true } }
      ]
    });

    // Séquence équilibrée
    this.predefinedSequences.set('balanced', {
      name: 'Balanced Workflow',
      description: 'Équilibré: Selective → Human → Adversarial → Pattern → Selective',
      phases: [
        { type: 'selective', config: { enabled: true, iteration: 1 } },
        { type: 'human', config: { enabled: true } },
        { type: 'adversarial', config: { enabled: true } },
        { type: 'pattern', config: { enabled: true } },
        { type: 'selective', config: { enabled: true, iteration: 2, intensity: 0.7 } }
      ]
    });

    logSh(`✅ WorkflowEngine: ${this.predefinedSequences.size} séquences prédéfinies chargées`, 'DEBUG');
  }

  // ========================================
  // EXÉCUTION WORKFLOW CONFIGURABLE
  // ========================================

  /**
   * Exécute un workflow selon une séquence configurée
   */
  async executeConfigurableWorkflow(content, config = {}) {
    return await tracer.run('WorkflowEngine.executeConfigurableWorkflow()', async () => {
      const {
        sequenceName = 'default',
        customSequence = null,
        selectiveConfig = {},
        adversarialConfig = {},
        humanConfig = {},
        patternConfig = {},
        csvData = {},
        personalities = {}
      } = config;

      await tracer.annotate({
        sequenceName: customSequence ? 'custom' : sequenceName,
        isCustomSequence: !!customSequence,
        elementsCount: Object.keys(content).length
      });

      logSh(`🔄 WORKFLOW CONFIGURABLE: ${customSequence ? 'custom' : sequenceName}`, 'INFO');

      let currentContent = { ...content };
      const workflowStats = {
        sequenceName: customSequence ? 'custom' : sequenceName,
        phases: [],
        totalDuration: 0,
        totalModifications: 0,
        versioning: new Map()
      };

      try {
        // Obtenir la séquence à exécuter
        const sequence = customSequence || this.getSequence(sequenceName);
        if (!sequence) {
          throw new Error(`Séquence workflow inconnue: ${sequenceName}`);
        }

        logSh(`   📋 Séquence: ${sequence.name} (${sequence.phases.length} phases)`, 'INFO');
        logSh(`   📝 Description: ${sequence.description}`, 'INFO');

        const startTime = Date.now();

        // Exécuter chaque phase de la séquence
        for (let i = 0; i < sequence.phases.length; i++) {
          const phase = sequence.phases[i];
          const phaseNumber = i + 1;

          logSh(`📊 PHASE ${phaseNumber}/${sequence.phases.length}: ${phase.type.toUpperCase()}${phase.config.iteration ? ` (${phase.config.iteration})` : ''}`, 'INFO');

          const phaseStartTime = Date.now();
          let phaseResult = null;

          try {
            switch (phase.type) {
              case 'selective':
                if (phase.config.enabled) {
                  phaseResult = await this.executeSelectivePhase(currentContent, {
                    ...selectiveConfig,
                    ...phase.config,
                    csvData,
                    personalities
                  });
                }
                break;

              case 'adversarial':
                if (phase.config.enabled) {
                  phaseResult = await this.executeAdversarialPhase(currentContent, {
                    ...adversarialConfig,
                    ...phase.config,
                    csvData,
                    personalities
                  });
                }
                break;

              case 'human':
                if (phase.config.enabled) {
                  phaseResult = await this.executeHumanPhase(currentContent, {
                    ...humanConfig,
                    ...phase.config,
                    csvData,
                    personalities
                  });
                }
                break;

              case 'pattern':
                if (phase.config.enabled) {
                  phaseResult = await this.executePatternPhase(currentContent, {
                    ...patternConfig,
                    ...phase.config,
                    csvData,
                    personalities
                  });
                }
                break;

              default:
                logSh(`⚠️ Type de phase inconnue: ${phase.type}`, 'WARNING');
            }

            // Mettre à jour le contenu et les stats
            if (phaseResult) {
              currentContent = phaseResult.content;

              const phaseDuration = Date.now() - phaseStartTime;
              const phaseStats = {
                type: phase.type,
                iteration: phase.config.iteration || 1,
                duration: phaseDuration,
                modifications: phaseResult.stats?.modifications || 0,
                success: true
              };

              workflowStats.phases.push(phaseStats);
              workflowStats.totalModifications += phaseStats.modifications;

              // Versioning
              const versionKey = `v1.${phaseNumber}`;
              workflowStats.versioning.set(versionKey, {
                phase: `${phase.type}${phase.config.iteration ? `-${phase.config.iteration}` : ''}`,
                content: { ...currentContent },
                timestamp: new Date().toISOString()
              });

              logSh(`   ✅ Phase ${phaseNumber} terminée: ${phaseStats.modifications} modifications en ${phaseDuration}ms`, 'DEBUG');
            } else {
              logSh(`   ⏭️ Phase ${phaseNumber} ignorée (désactivée)`, 'DEBUG');
            }

          } catch (error) {
            logSh(`   ❌ Erreur phase ${phaseNumber} (${phase.type}): ${error.message}`, 'ERROR');

            workflowStats.phases.push({
              type: phase.type,
              iteration: phase.config.iteration || 1,
              duration: Date.now() - phaseStartTime,
              modifications: 0,
              success: false,
              error: error.message
            });
          }
        }

        workflowStats.totalDuration = Date.now() - startTime;

        // Version finale
        workflowStats.versioning.set('v2.0', {
          phase: 'final',
          content: { ...currentContent },
          timestamp: new Date().toISOString()
        });

        logSh(`✅ WORKFLOW TERMINÉ: ${workflowStats.totalModifications} modifications en ${workflowStats.totalDuration}ms`, 'INFO');

        return {
          content: currentContent,
          stats: workflowStats,
          success: true
        };

      } catch (error) {
        logSh(`❌ Erreur workflow configurable: ${error.message}`, 'ERROR');

        workflowStats.totalDuration = Date.now() - startTime;
        workflowStats.error = error.message;

        return {
          content: currentContent,
          stats: workflowStats,
          success: false,
          error: error.message
        };
      }
    });
  }

  // ========================================
  // EXÉCUTION DES PHASES INDIVIDUELLES
  // ========================================

  async executeSelectivePhase(content, config) {
    const result = await applySelectiveEnhancement(content, config);
    return {
      content: result.content || content,
      stats: { modifications: result.stats?.selectiveEnhancements || 0 }
    };
  }

  async executeAdversarialPhase(content, config) {
    const result = await applyAdversarialEnhancement(content, config);
    return {
      content: result.content || content,
      stats: { modifications: result.stats?.adversarialModifications || 0 }
    };
  }

  async executeHumanPhase(content, config) {
    const result = await applyHumanSimulation(content, config);
    return {
      content: result.content || content,
      stats: { modifications: result.stats?.humanSimulationModifications || 0 }
    };
  }

  async executePatternPhase(content, config) {
    const result = await applyPatternBreaking(content, config);
    return {
      content: result.content || content,
      stats: { modifications: result.stats?.patternBreakingModifications || 0 }
    };
  }

  // ========================================
  // GESTION DES SÉQUENCES
  // ========================================

  /**
   * Obtenir une séquence (prédéfinie ou personnalisée)
   */
  getSequence(sequenceName) {
    return this.predefinedSequences.get(sequenceName) || this.customSequences.get(sequenceName);
  }

  /**
   * Créer une séquence personnalisée
   */
  createCustomSequence(name, sequence) {
    this.customSequences.set(name, sequence);
    logSh(`✨ Séquence personnalisée créée: ${name}`, 'INFO');
    return sequence;
  }

  /**
   * Lister toutes les séquences disponibles
   */
  getAvailableSequences() {
    const sequences = [];

    // Séquences prédéfinies
    for (const [name, sequence] of this.predefinedSequences) {
      sequences.push({
        name,
        ...sequence,
        isCustom: false
      });
    }

    // Séquences personnalisées
    for (const [name, sequence] of this.customSequences) {
      sequences.push({
        name,
        ...sequence,
        isCustom: true
      });
    }

    return sequences;
  }

  /**
   * Valider une séquence
   */
  validateSequence(sequence) {
    if (!sequence.name || !sequence.phases || !Array.isArray(sequence.phases)) {
      return false;
    }

    const validTypes = ['selective', 'adversarial', 'human', 'pattern'];

    for (const phase of sequence.phases) {
      if (!phase.type || !validTypes.includes(phase.type)) {
        return false;
      }
      if (!phase.config || typeof phase.config !== 'object') {
        return false;
      }
    }

    return true;
  }

  /**
   * Obtenir le statut du moteur
   */
  getEngineStatus() {
    return {
      predefinedSequences: Array.from(this.predefinedSequences.keys()),
      customSequences: Array.from(this.customSequences.keys()),
      totalSequences: this.predefinedSequences.size + this.customSequences.size,
      availablePhaseTypes: ['selective', 'adversarial', 'human', 'pattern']
    };
  }
}

// ============= EXPORTS =============
module.exports = { WorkflowEngine };