/**
 * REPORTER AUTOMATIQUE POUR TESTS D'INTÉGRATION
 * Génère automatiquement un rapport HTML détaillé
 * S'interface avec le système de logging existant pour capturer les LLM calls
 */

import fs from 'fs';
import path from 'path';

class TestReporter {
  constructor() {
    this.results = [];
    this.startTime = Date.now();
    this.currentTest = null;
    this.reportDir = path.join(process.cwd(), 'reports');
    this.originalConsoleLog = console.log;

    // Créer le dossier reports s'il n'existe pas
    if (!fs.existsSync(this.reportDir)) {
      fs.mkdirSync(this.reportDir, { recursive: true });
    }

    // Hook dans les logs pour capturer automatiquement les LLM calls
    this.hookLogging();
  }

  hookLogging() {
    // Capture automatique des logs JSON pour extraire les stats LLM
    const originalStdout = process.stdout.write;
    process.stdout.write = (chunk, encoding, callback) => {
      const str = chunk.toString();

      // Capturer les stats LLM depuis les logs JSON
      if (str.includes('"msg":"📊 Stats:') && this.currentTest) {
        try {
          const logLine = JSON.parse(str.trim());
          const statsMatch = logLine.msg.match(/📊 Stats: ({.*})/);
          if (statsMatch) {
            const stats = JSON.parse(statsMatch[1]);
            this.currentTest.llmCalls.push({
              provider: stats.provider,
              model: stats.model,
              duration: stats.duration,
              tokens: {
                promptTokens: stats.promptTokens,
                responseTokens: stats.responseTokens
              },
              timestamp: stats.timestamp,
              input: 'Captured from logs',
              output: 'Captured from logs'
            });
          }
        } catch (e) {
          // Ignore parsing errors
        }
      }

      return originalStdout.call(process.stdout, chunk, encoding, callback);
    };
  }

  startTest(testName, config = {}) {
    this.currentTest = {
      name: testName,
      startTime: Date.now(),
      config,
      llmCalls: [],
      results: null,
      error: null,
      status: 'running'
    };
  }

  recordLLMCall(provider, model, input, output, duration, tokens = {}) {
    if (!this.currentTest) return;

    this.currentTest.llmCalls.push({
      provider,
      model,
      input: typeof input === 'string' ? input.substring(0, 500) + '...' : JSON.stringify(input).substring(0, 500) + '...',
      output: typeof output === 'string' ? output.substring(0, 1000) + '...' : JSON.stringify(output).substring(0, 1000) + '...',
      duration,
      tokens,
      timestamp: Date.now()
    });
  }

  endTest(results = null, error = null) {
    if (!this.currentTest) return;

    this.currentTest.endTime = Date.now();
    this.currentTest.duration = this.currentTest.endTime - this.currentTest.startTime;
    this.currentTest.results = results;
    this.currentTest.error = error;
    this.currentTest.status = error ? 'failed' : 'passed';

    this.results.push({ ...this.currentTest });
    this.currentTest = null;
  }

  generateReport() {
    const totalDuration = Date.now() - this.startTime;
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const reportFile = path.join(this.reportDir, `ti-report-${timestamp}.html`);

    const stats = {
      total: this.results.length,
      passed: this.results.filter(r => r.status === 'passed').length,
      failed: this.results.filter(r => r.status === 'failed').length,
      totalDuration,
      avgDuration: this.results.length ? totalDuration / this.results.length : 0,
      totalLLMCalls: this.results.reduce((sum, r) => sum + r.llmCalls.length, 0)
    };

    const html = this.generateHTML(stats);
    fs.writeFileSync(reportFile, html);

    // Générer aussi le JSON pour analyse programmatique
    const jsonFile = path.join(this.reportDir, `ti-report-${timestamp}.json`);
    fs.writeFileSync(jsonFile, JSON.stringify({
      timestamp: new Date().toISOString(),
      stats,
      results: this.results
    }, null, 2));

    console.log(`\n📊 RAPPORT GÉNÉRÉ AUTOMATIQUEMENT:`);
    console.log(`   HTML: ${reportFile}`);
    console.log(`   JSON: ${jsonFile}`);
    console.log(`   📈 ${stats.passed}/${stats.total} tests passés | ${stats.totalLLMCalls} appels LLM | ${totalDuration}ms total`);

    return reportFile;
  }

  generateHTML(stats) {
    return `<!DOCTYPE html>
<html>
<head>
    <title>Rapport Tests d'Intégration - ${new Date().toLocaleString()}</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; background: #f5f5f5; }
        .container { max-width: 1200px; margin: 0 auto; }
        .header { background: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-bottom: 20px; }
        .stat-card { background: white; padding: 15px; border-radius: 8px; text-align: center; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        .stat-value { font-size: 2em; font-weight: bold; color: #2196F3; }
        .stat-label { color: #666; margin-top: 5px; }
        .test-item { background: white; margin-bottom: 15px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        .test-header { padding: 15px; cursor: pointer; border-bottom: 1px solid #eee; }
        .test-header:hover { background: #f9f9f9; }
        .test-status { display: inline-block; width: 12px; height: 12px; border-radius: 50%; margin-right: 10px; }
        .status-passed { background: #4CAF50; }
        .status-failed { background: #f44336; }
        .test-details { padding: 15px; display: none; }
        .llm-call { background: #f9f9f9; padding: 10px; margin: 10px 0; border-radius: 4px; border-left: 4px solid #2196F3; }
        .config { background: #e3f2fd; padding: 10px; border-radius: 4px; margin: 10px 0; }
        .input-output { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }
        .input, .output { background: #f5f5f5; padding: 10px; border-radius: 4px; font-family: monospace; font-size: 12px; }
        .metrics { display: flex; gap: 20px; margin: 10px 0; }
        .metric { background: white; padding: 8px 12px; border-radius: 4px; font-size: 12px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📊 Rapport Tests d'Intégration Modulaire</h1>
            <p>Généré automatiquement le ${new Date().toLocaleString()}</p>
        </div>

        <div class="stats">
            <div class="stat-card">
                <div class="stat-value">${stats.total}</div>
                <div class="stat-label">Tests Total</div>
            </div>
            <div class="stat-card">
                <div class="stat-value" style="color: #4CAF50">${stats.passed}</div>
                <div class="stat-label">Tests Réussis</div>
            </div>
            <div class="stat-card">
                <div class="stat-value" style="color: #f44336">${stats.failed}</div>
                <div class="stat-label">Tests Échoués</div>
            </div>
            <div class="stat-card">
                <div class="stat-value">${stats.totalLLMCalls}</div>
                <div class="stat-label">Appels LLM</div>
            </div>
            <div class="stat-card">
                <div class="stat-value">${Math.round(stats.totalDuration / 1000)}s</div>
                <div class="stat-label">Durée Totale</div>
            </div>
            <div class="stat-card">
                <div class="stat-value">${Math.round(stats.avgDuration / 1000)}s</div>
                <div class="stat-label">Durée Moyenne</div>
            </div>
        </div>

        <div class="tests">
            ${this.results.map((test, index) => `
                <div class="test-item">
                    <div class="test-header" onclick="toggleDetails(${index})">
                        <span class="test-status status-${test.status}"></span>
                        <strong>${test.name}</strong>
                        <span style="float: right; color: #666;">${Math.round(test.duration / 1000)}s | ${test.llmCalls.length} LLM calls</span>
                    </div>
                    <div class="test-details" id="details-${index}">
                        ${test.config ? `
                            <div class="config">
                                <strong>Configuration:</strong>
                                <pre>${JSON.stringify(test.config, null, 2)}</pre>
                            </div>
                        ` : ''}

                        ${test.results ? `
                            <div class="config">
                                <strong>Résultats:</strong>
                                <div class="metrics">
                                    ${test.results.stats ? Object.entries(test.results.stats).map(([key, value]) =>
                                        `<div class="metric"><strong>${key}:</strong> ${value}</div>`
                                    ).join('') : ''}
                                </div>
                            </div>
                        ` : ''}

                        ${test.error ? `
                            <div style="background: #ffebee; padding: 10px; border-radius: 4px; color: #c62828;">
                                <strong>Erreur:</strong> ${test.error}
                            </div>
                        ` : ''}

                        <h4>Appels LLM (${test.llmCalls.length})</h4>
                        ${test.llmCalls.map((call, callIndex) => `
                            <div class="llm-call">
                                <div class="metrics">
                                    <div class="metric"><strong>Provider:</strong> ${call.provider}</div>
                                    <div class="metric"><strong>Model:</strong> ${call.model}</div>
                                    <div class="metric"><strong>Durée:</strong> ${call.duration}ms</div>
                                    ${call.tokens.promptTokens ? `<div class="metric"><strong>Tokens:</strong> ${call.tokens.promptTokens}→${call.tokens.responseTokens}</div>` : ''}
                                </div>
                                <div class="input-output">
                                    <div>
                                        <strong>Input:</strong>
                                        <div class="input">${call.input}</div>
                                    </div>
                                    <div>
                                        <strong>Output:</strong>
                                        <div class="output">${call.output}</div>
                                    </div>
                                </div>
                            </div>
                        `).join('')}
                    </div>
                </div>
            `).join('')}
        </div>
    </div>

    <script>
        function toggleDetails(index) {
            const details = document.getElementById('details-' + index);
            details.style.display = details.style.display === 'none' ? 'block' : 'none';
        }
    </script>
</body>
</html>`;
  }
}

export { TestReporter };