import { AutoReporter } from '../reporters/AutoReporter.js';
import assert from 'node:assert';
import { test, describe, before, after } from 'node:test';
import axios from 'axios';
import { requireCommonJS } from '../_helpers/commonjs-bridge.js';

// ========================================
// TESTS D'INTÉGRATION - COHÉRENCE APIs
// Description: Valide que toutes les APIs utilisent le même système
// ========================================

// Imports système
const { ManualServer } = requireCommonJS('modes/ManualServer');
const { sessionManager } = requireCommonJS('StepByStepSessionManager');


// Auto-Reporter Configuration
const autoReporter = new AutoReporter();

describe('🔥 Tests cohérence APIs - Step-by-step vs Generate-simple vs Main', () => {

  let server;
  let baseURL = 'http://localhost:3002'; // Port test

  before(async () => {
    // Démarrer serveur test
    server = new ManualServer({ port: 3002, wsPort: 8082 });
    await server.start();
    console.log('🚀 Serveur test démarré sur port 3002');
  });

  after(async () => {
    if (server) {
      await server.stop();
      console.log('🛑 Serveur test arrêté');
    }
  });

  // ========================================
  // TEST: MÊME COMPORTEMENT STEP-BY-STEP vs API SIMPLE
  // ========================================

  test('🔥 CRITIQUE: Step-by-step et Generate-simple donnent des résultats cohérents', async () => {
    console.log('🧪 Test cohérence step-by-step ↔ generate-simple...');

    const testKeyword = 'plaque test cohérence';

    // ============= TEST GENERATE-SIMPLE =============
    console.log('📡 Test /api/generate-simple...');
    const simpleResponse = await axios.post(`${baseURL}/api/generate-simple`, {
      keyword: testKeyword
    });

    assert.ok(simpleResponse.data.success, 'Generate-simple doit réussir');
    assert.ok(simpleResponse.data.article, 'Doit retourner un article');

    const simpleArticle = simpleResponse.data.article;
    console.log(`📊 Generate-simple: ${JSON.stringify(simpleArticle).length} chars`);

    // ============= TEST STEP-BY-STEP =============
    console.log('📡 Test step-by-step workflow...');

    // Étape 1: Initialisation
    const initResponse = await axios.post(`${baseURL}/api/step-by-step/init`, {
      t0: `Guide complet sur ${testKeyword}`,
      mc0: testKeyword,
      personality: 'Marc'
    });

    assert.ok(initResponse.data.success, 'Step-by-step init doit réussir');
    const sessionId = initResponse.data.sessionId;
    console.log(`📊 Session step-by-step: ${sessionId}`);

    // Étape 2: Génération initiale
    const genResponse = await axios.post(`${baseURL}/api/step-by-step/execute`, {
      sessionId,
      stepId: 1,
      options: {}
    });

    assert.ok(genResponse.data.success, 'Step génération initiale doit réussir');
    assert.ok(genResponse.data.result.content, 'Doit générer du contenu');

    const stepContent = genResponse.data.result.content;
    console.log(`📊 Step-by-step: ${Object.keys(stepContent).length} éléments`);

    // ============= VALIDATIONS COHÉRENCE =============

    // Valider que les deux approches génèrent du contenu
    assert.ok(simpleArticle.content, 'Generate-simple doit avoir du contenu');
    assert.ok(Object.keys(stepContent).length > 0, 'Step-by-step doit avoir des éléments');

    // Valider cohérence du mot-clé
    const simpleText = JSON.stringify(simpleArticle).toLowerCase();
    const stepText = JSON.stringify(stepContent).toLowerCase();

    assert.ok(simpleText.includes(testKeyword.toLowerCase()),
      'Generate-simple doit contenir le mot-clé');
    assert.ok(stepText.includes(testKeyword.toLowerCase()),
      'Step-by-step doit contenir le mot-clé');

    console.log('✅ Cohérence step-by-step ↔ generate-simple validée');

  }, { timeout: 90000 });

  // ========================================
  // TEST: OPTIONS SELECTIVESTACK DANS STEP-BY-STEP
  // ========================================

  test('🔥 CRITIQUE: Options selectiveStack vraiment appliquées dans step-by-step', async () => {
    console.log('🧪 Test options selectiveStack step-by-step...');

    const testData = {
      t0: 'Test options selective',
      mc0: 'test selective stack',
      personality: 'Marc'
    };

    // ============= TEST AVEC LIGHTENHANCEMENT =============
    const initLight = await axios.post(`${baseURL}/api/step-by-step/init`, testData);
    const sessionLight = initLight.data.sessionId;

    // Génération initiale
    const genLight = await axios.post(`${baseURL}/api/step-by-step/execute`, {
      sessionId: sessionLight,
      stepId: 1
    });

    // Selective avec lightEnhancement
    const selectiveLight = await axios.post(`${baseURL}/api/step-by-step/execute`, {
      sessionId: sessionLight,
      stepId: 2,
      options: { selectiveStack: 'lightEnhancement' }
    });

    // ============= TEST AVEC STANDARDENHANCEMENT =============
    const initStandard = await axios.post(`${baseURL}/api/step-by-step/init`, testData);
    const sessionStandard = initStandard.data.sessionId;

    // Génération initiale
    const genStandard = await axios.post(`${baseURL}/api/step-by-step/execute`, {
      sessionId: sessionStandard,
      stepId: 1
    });

    // Selective avec standardEnhancement
    const selectiveStandard = await axios.post(`${baseURL}/api/step-by-step/execute`, {
      sessionId: sessionStandard,
      stepId: 2,
      options: { selectiveStack: 'standardEnhancement' }
    });

    // ============= VALIDATIONS =============
    assert.ok(selectiveLight.data.success, 'lightEnhancement doit réussir');
    assert.ok(selectiveStandard.data.success, 'standardEnhancement doit réussir');

    const lightResult = selectiveLight.data.result.content;
    const standardResult = selectiveStandard.data.result.content;

    console.log(`📊 Light enhancement: ${Object.keys(lightResult).length} éléments`);
    console.log(`📊 Standard enhancement: ${Object.keys(standardResult).length} éléments`);

    // Les deux doivent avoir du contenu
    assert.ok(Object.keys(lightResult).length > 0, 'lightEnhancement doit générer du contenu');
    assert.ok(Object.keys(standardResult).length > 0, 'standardEnhancement doit générer du contenu');

    // Valider que les options sont bien passées (via logs ou différences)
    const lightText = JSON.stringify(lightResult);
    const standardText = JSON.stringify(standardResult);

    console.log(`📊 Différence contenu: ${Math.abs(lightText.length - standardText.length)} chars`);

    console.log('✅ Options selectiveStack appliquées dans step-by-step');

  }, { timeout: 120000 });

  // ========================================
  // TEST: ADVERSARIAL MODE MAPPING
  // ========================================

  test('🔥 CRITIQUE: Adversarial mode mapping fonctionne dans APIs', async () => {
    console.log('🧪 Test adversarial mode mapping...');

    const testData = {
      t0: 'Test adversarial mapping',
      mc0: 'test adversarial mode',
      personality: 'Marc'
    };

    // ============= INIT SESSION =============
    const initResponse = await axios.post(`${baseURL}/api/step-by-step/init`, testData);
    const sessionId = initResponse.data.sessionId;

    // Génération initiale
    await axios.post(`${baseURL}/api/step-by-step/execute`, {
      sessionId,
      stepId: 1
    });

    // ============= TEST ADVERSARIAL LIGHT =============
    const adversarialResponse = await axios.post(`${baseURL}/api/step-by-step/execute`, {
      sessionId,
      stepId: 3, // adversarial step
      options: { adversarialMode: 'light' }
    });

    // ============= VALIDATIONS =============
    assert.ok(adversarialResponse.data.success, 'Adversarial mode=light doit réussir');

    const result = adversarialResponse.data.result;
    assert.ok(result.content, 'Adversarial doit retourner du contenu');

    console.log(`📊 Adversarial result: ${Object.keys(result.content).length} éléments`);

    // Valider que le mode 'light' est bien mappé vers 'lightDefense'
    // (cela sera visible dans les logs de debug si activés)

    console.log('✅ Adversarial mode mapping fonctionne');

  }, { timeout: 90000 });

  // ========================================
  // TEST: STATUS ET MONITORING APIS
  // ========================================

  test('🔥 CRITIQUE: APIs status et monitoring fonctionnent', async () => {
    console.log('🧪 Test APIs status et monitoring...');

    // ============= TEST STATUS =============
    const statusResponse = await axios.get(`${baseURL}/api/status`);

    assert.ok(statusResponse.data.success, 'API status doit réussir');
    assert.equal(statusResponse.data.mode, 'MANUAL', 'Doit être en mode MANUAL');
    assert.equal(statusResponse.data.status, 'running', 'Serveur doit être running');

    console.log(`📊 Uptime: ${statusResponse.data.uptime}ms`);
    console.log(`📊 Requests: ${statusResponse.data.stats.requests}`);

    // ============= TEST STATS =============
    const statsResponse = await axios.get(`${baseURL}/api/stats`);

    assert.ok(statsResponse.data.success, 'API stats doit réussir');
    assert.ok(statsResponse.data.stats, 'Doit retourner des stats');

    console.log(`📊 Memory: ${JSON.stringify(statsResponse.data.stats.memory).length} chars`);

    // ============= TEST CONFIG MODULAIRE =============
    const configResponse = await axios.get(`${baseURL}/api/modulaire-config`);

    assert.ok(configResponse.data.success, 'API config doit réussir');
    assert.ok(configResponse.data.config.selectiveStacks, 'Doit avoir config selective');
    assert.ok(configResponse.data.config.adversarialModes, 'Doit avoir config adversarial');

    const selectiveStacks = configResponse.data.config.selectiveStacks;
    const adversarialModes = configResponse.data.config.adversarialModes;

    console.log(`📊 Selective stacks: ${selectiveStacks.length}`);
    console.log(`📊 Adversarial modes: ${adversarialModes.length}`);

    // Valider que les stacks importantes sont présentes
    const stackNames = selectiveStacks.map(s => s.value);
    assert.ok(stackNames.includes('lightEnhancement'), 'lightEnhancement doit être disponible');
    assert.ok(stackNames.includes('standardEnhancement'), 'standardEnhancement doit être disponible');

    const modeNames = adversarialModes.map(m => m.value);
    assert.ok(modeNames.includes('light'), 'Adversarial light doit être disponible');
    assert.ok(modeNames.includes('standard'), 'Adversarial standard doit être disponible');

    console.log('✅ APIs status et monitoring fonctionnent');

  }, { timeout: 30000 });

  // ========================================
  // TEST: GESTION ERREURS ET ROBUSTESSE
  // ========================================

  test('🔥 CRITIQUE: Gestion erreurs APIs robuste', async () => {
    console.log('🧪 Test gestion erreurs...');

    // ============= TEST DONNÉES INVALIDES =============
    try {
      const invalidResponse = await axios.post(`${baseURL}/api/generate-simple`, {
        keyword: '' // Mot-clé vide
      });

      // Doit retourner une erreur 400
      assert.equal(invalidResponse.status, 400, 'Doit retourner erreur 400 pour données invalides');

    } catch (error) {
      assert.equal(error.response.status, 400, 'Doit capturer erreur 400');
      assert.ok(error.response.data.error, 'Doit retourner message d\'erreur');
      console.log(`📊 Erreur capturée: ${error.response.data.error}`);
    }

    // ============= TEST SESSION INEXISTANTE =============
    try {
      const invalidSession = await axios.post(`${baseURL}/api/step-by-step/execute`, {
        sessionId: 'session_inexistante',
        stepId: 1
      });

      // Doit échouer gracieusement
      assert.ok(!invalidSession.data.success || invalidSession.status >= 400,
        'Session inexistante doit échouer');

    } catch (error) {
      assert.ok(error.response.status >= 400, 'Doit retourner erreur pour session inexistante');
      console.log(`📊 Session inexistante gérée: ${error.response.status}`);
    }

    console.log('✅ Gestion erreurs robuste');

  }, { timeout: 30000 });

});