const express = require('express');
const router = express.Router();
const pm = require('../services/project-manager');
const fs = require('fs');
const path = require('path');

router.get('/', (req, res) => {
  const projectId = req.query.project;
  const project = projectId ? pm.get(projectId) : pm.getAll()[0];
  if (!project) return res.redirect('/projects');

  const bridge = pm.getBridge(project.id);
  const runDirs = bridge.getRunDirs();

  const hasAllure = bridge.hasAllureReport();
  const runs = runDirs.map(d => {
    const result = bridge.getRunResult(d.name);
    const healing = bridge.getHealingReport(d.name);
    return {
      id: d.name,
      timestamp: d.name.replace('run-', '').replace(/-/g, ':').slice(0, 19),
      success: result ? result.success : null,
      duration: result ? result.duration : null,
      failedCount: result && Array.isArray(result.failedTests) ? result.failedTests.length : 0,
      passedCount: result && Array.isArray(result.passedTests) ? result.passedTests.length : 0,
      healedCount: healing ? healing.totalHealed || 0 : 0,
      hasReport: !!bridge.getFinalReport(d.name),
      hasAllure,
      testName: result ? result.test : 'Unknown',
    };
  });

  res.render('runs', { project, runs });
});

router.get('/:runId', (req, res) => {
  const projectId = req.query.project;
  const project = projectId ? pm.get(projectId) : pm.getAll()[0];
  if (!project) return res.redirect('/projects');

  const bridge = pm.getBridge(project.id);
  
  // Validation de l'existence du dossier de run
  const runDirs = bridge.getRunDirs();
  const runExists = runDirs.some(d => d.name === req.params.runId);
  if (!runExists) return res.status(404).render('error', { message: 'Run not found' });

  // Récupération des résultats ou fallback dynamique (en cours d'exécution)
  let result = bridge.getRunResult(req.params.runId);
  if (!result) {
    const outputPath = path.join(bridge.projectPath, 'test-results', req.params.runId, 'execution-output.json');
    let outputText = 'No console output captured yet.';
    if (fs.existsSync(outputPath)) {
      try {
        outputText = fs.readFileSync(outputPath, 'utf-8');
      } catch (err) {}
    }
    
    result = {
      runId: req.params.runId,
      success: null,
      duration: null,
      test: 'Running / In Progress...',
      timestamp: new Date().toISOString(),
      failedTests: [],
      passedTests: [],
      output: outputText
    };
  }

  const healing = bridge.getHealingReport(req.params.runId);
  const report = bridge.getFinalReport(req.params.runId);
  const hasAllure = bridge.hasAllureReport();

  res.render('run', { project, run: { id: req.params.runId, result, healing, report, hasAllure } });
});

router.get('/:runId/compare/:otherRunId', (req, res) => {
  const projectId = req.query.project;
  const project = projectId ? pm.get(projectId) : pm.getAll()[0];
  if (!project) return res.redirect('/projects');

  const bridge = pm.getBridge(project.id);
  const result1 = bridge.getRunResult(req.params.runId);
  const result2 = bridge.getRunResult(req.params.otherRunId);
  if (!result1 || !result2) return res.status(404).render('error', { message: 'Run not found' });

  const hasAllure = bridge.hasAllureReport();

  res.render('runs', { project, runs: [
    { 
      id: req.params.runId, 
      success: result1.success, 
      duration: result1.duration, 
      testName: result1.test || 'Unknown', 
      failedCount: Array.isArray(result1.failedTests) ? result1.failedTests.length : 0, 
      passedCount: Array.isArray(result1.passedTests) ? result1.passedTests.length : 0, 
      healedCount: 0, 
      hasReport: !!bridge.getFinalReport(req.params.runId), 
      hasAllure,
      timestamp: result1.timestamp ? result1.timestamp.replace('T', ' ').slice(0, 19) : '' 
    },
    { 
      id: req.params.otherRunId, 
      success: result2.success, 
      duration: result2.duration, 
      testName: result2.test || 'Unknown', 
      failedCount: Array.isArray(result2.failedTests) ? result2.failedTests.length : 0, 
      passedCount: Array.isArray(result2.passedTests) ? result2.passedTests.length : 0, 
      healedCount: 0, 
      hasReport: !!bridge.getFinalReport(req.params.otherRunId), 
      hasAllure,
      timestamp: result2.timestamp ? result2.timestamp.replace('T', ' ').slice(0, 19) : '' 
    },
  ] });
});

// Rerun a specific test from a previous run
router.post('/:runId/rerun', (req, res) => {
  const projectId = req.query.project;
  const project = projectId ? pm.get(projectId) : pm.getAll()[0];
  if (!project) return res.status(404).json({ error: 'Project not found' });

  const bridge = pm.getBridge(project.id);
  const result = bridge.getRunResult(req.params.runId);
  if (!result) return res.status(404).json({ error: 'Run not found' });

  const testName = result.test || '';
  if (!testName || testName === 'all') {
    // Rerun all tests
    const runResult = bridge.execute('');
    return res.json({ success: runResult.success, output: runResult.output, error: runResult.error });
  }

  const runResult = bridge.execute(testName);
  res.json({ success: runResult.success, output: runResult.output, error: runResult.error, runId: extractRunId(runResult.output) });
});

// Regenerate Allure report
router.post('/allure-regenerate', (req, res) => {
  const projectId = req.query.project;
  const project = projectId ? pm.get(projectId) : pm.getAll()[0];
  if (!project) return res.status(404).json({ error: 'Project not found' });

  const bridge = pm.getBridge(project.id);
  const result = bridge.runCommand('npx allure generate allure-results --clean -o allure-report');
  res.json({ success: result.success, output: result.output, error: result.error });
});

function extractRunId(output) {
  if (!output) return null;
  const match = output.match(/run-[\d-T-]+/);
  return match ? match[0] : null;
}

module.exports = router;
