#!/usr/bin/env node

/**
 * Script de tests de production pour Veza V5 Ultra
 * Objectif: 100% tests passés, 0 bugs critiques
 */

const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

console.log('🧪 VEZA V5 ULTRA - Production Tests');
console.log('===================================\n');

// Configuration des tests
const testConfig = {
  unit: {
    command: 'npm run test:unit',
    coverage: 80,
    timeout: 30000,
  },
  e2e: {
    command: 'npm run test:e2e',
    timeout: 60000,
  },
  lighthouse: {
    command: 'npm run lighthouse:ci',
    score: 100,
  },
  performance: {
    command: 'npm run test:perf',
    fcp: 0.8, // First Contentful Paint < 0.8s
    tti: 1.5, // Time to Interactive < 1.5s
    cls: 0.1, // Cumulative Layout Shift < 0.1
  },
  accessibility: {
    command: 'npm run test:a11y',
    score: 100,
  },
};

// Fonction pour exécuter un test
function runTest(name, config) {
  console.log(`\n🔍 Running ${name}...`);
  
  try {
    const startTime = Date.now();
    const result = execSync(config.command, { 
      encoding: 'utf8',
      timeout: config.timeout || 30000,
      stdio: 'pipe'
    });
    
    const duration = (Date.now() - startTime) / 1000;
    console.log(`✅ ${name} passed in ${duration.toFixed(2)}s`);
    
    // Analyser les résultats spécifiques
    if (name === 'Unit Tests' && config.coverage) {
      const coverageMatch = result.match(/(\d+)%/);
      if (coverageMatch) {
        const coverage = parseInt(coverageMatch[1]);
        if (coverage >= config.coverage) {
          console.log(`✅ Coverage: ${coverage}% (target: ${config.coverage}%)`);
        } else {
          console.log(`⚠️  Coverage: ${coverage}% (target: ${config.coverage}%)`);
        }
      }
    }
    
    if (name === 'Lighthouse' && config.score) {
      const scoreMatch = result.match(/Performance: (\d+)/);
      if (scoreMatch) {
        const score = parseInt(scoreMatch[1]);
        if (score >= config.score) {
          console.log(`✅ Lighthouse Score: ${score}/100`);
        } else {
          console.log(`⚠️  Lighthouse Score: ${score}/100 (target: ${config.score})`);
        }
      }
    }
    
    return { success: true, duration, result };
  } catch (error) {
    console.log(`❌ ${name} failed:`, error.message);
    return { success: false, error: error.message };
  }
}

// Fonction pour vérifier les métriques de performance
function checkPerformanceMetrics() {
  console.log('\n📊 Checking Performance Metrics...');
  
  const metrics = {
    bundleSize: checkBundleSize(),
    buildTime: checkBuildTime(),
    memoryUsage: checkMemoryUsage(),
  };
  
  return metrics;
}

function checkBundleSize() {
  const distPath = path.join(__dirname, '..', 'dist');
  if (!fs.existsSync(distPath)) {
    return { error: 'No dist folder found' };
  }
  
  let totalSize = 0;
  let jsFiles = [];
  
  function scanDir(dir) {
    const files = fs.readdirSync(dir);
    files.forEach(file => {
      const filePath = path.join(dir, file);
      if (fs.statSync(filePath).isDirectory()) {
        scanDir(filePath);
      } else if (file.endsWith('.js')) {
        const size = fs.statSync(filePath).size;
        totalSize += size;
        jsFiles.push({ name: file, size });
      }
    });
  }
  
  scanDir(distPath);
  
  const initialBundle = jsFiles.find(f => f.name.includes('index'))?.size || 0;
  const maxChunk = Math.max(...jsFiles.map(f => f.size));
  
  return {
    total: totalSize,
    initial: initialBundle,
    maxChunk,
    files: jsFiles.length,
    target: 150 * 1024, // 150KB
  };
}

function checkBuildTime() {
  const startTime = Date.now();
  try {
    execSync('npm run build', { stdio: 'pipe' });
    return Date.now() - startTime;
  } catch (error) {
    return { error: error.message };
  }
}

function checkMemoryUsage() {
  const usage = process.memoryUsage();
  return {
    rss: Math.round(usage.rss / 1024 / 1024), // MB
    heapUsed: Math.round(usage.heapUsed / 1024 / 1024), // MB
    heapTotal: Math.round(usage.heapTotal / 1024 / 1024), // MB
  };
}

// Fonction pour générer le rapport de tests
function generateTestReport(results) {
  const report = {
    timestamp: new Date().toISOString(),
    summary: {
      total: Object.keys(testConfig).length,
      passed: Object.values(results).filter(r => r.success).length,
      failed: Object.values(results).filter(r => !r.success).length,
    },
    results,
    performance: checkPerformanceMetrics(),
  };
  
  const reportPath = path.join(__dirname, '..', 'test-report-production.json');
  fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
  
  console.log(`\n📄 Test report saved to: ${reportPath}`);
  return report;
}

// Exécuter tous les tests
async function runAllTests() {
  console.log('🚀 Starting Production Test Suite...\n');
  
  const results = {};
  
  // Tests unitaires
  results.unit = runTest('Unit Tests', testConfig.unit);
  
  // Tests E2E
  results.e2e = runTest('E2E Tests', testConfig.e2e);
  
  // Tests Lighthouse
  results.lighthouse = runTest('Lighthouse', testConfig.lighthouse);
  
  // Tests de performance
  results.performance = runTest('Performance Tests', testConfig.performance);
  
  // Tests d'accessibilité
  results.accessibility = runTest('Accessibility Tests', testConfig.accessibility);
  
  // Générer le rapport
  const report = generateTestReport(results);
  
  // Afficher le résumé
  console.log('\n📋 TEST SUMMARY');
  console.log('================');
  console.log(`Total Tests: ${report.summary.total}`);
  console.log(`Passed: ${report.summary.passed} ✅`);
  console.log(`Failed: ${report.summary.failed} ❌`);
  console.log(`Success Rate: ${((report.summary.passed / report.summary.total) * 100).toFixed(1)}%`);
  
  // Métriques de performance
  console.log('\n📊 PERFORMANCE METRICS');
  console.log('======================');
  if (report.performance.bundleSize) {
    const bundle = report.performance.bundleSize;
    console.log(`Bundle Size: ${(bundle.initial / 1024).toFixed(2)} KB (target: < 150 KB)`);
    console.log(`Max Chunk: ${(bundle.maxChunk / 1024).toFixed(2)} KB (target: < 50 KB)`);
    console.log(`Total Files: ${bundle.files}`);
  }
  
  if (report.performance.buildTime) {
    console.log(`Build Time: ${(report.performance.buildTime / 1000).toFixed(2)}s`);
  }
  
  if (report.performance.memoryUsage) {
    const mem = report.performance.memoryUsage;
    console.log(`Memory Usage: ${mem.heapUsed}MB / ${mem.heapTotal}MB`);
  }
  
  // Recommandations
  console.log('\n💡 RECOMMENDATIONS');
  console.log('==================');
  
  if (report.summary.failed > 0) {
    console.log('❌ Fix failing tests before production deployment');
  }
  
  if (report.performance.bundleSize?.initial > report.performance.bundleSize?.target) {
    console.log('⚠️  Bundle size too large - consider code splitting');
  }
  
  if (report.performance.buildTime > 30000) {
    console.log('⚠️  Build time too slow - consider optimization');
  }
  
  if (report.summary.passed === report.summary.total) {
    console.log('🎉 All tests passed! Ready for production deployment');
  }
  
  return report.summary.passed === report.summary.total;
}

// Exécuter les tests
runAllTests().then(success => {
  process.exit(success ? 0 : 1);
}).catch(error => {
  console.error('❌ Test suite failed:', error);
  process.exit(1);
});
