import { tap, expect } from '@push.rocks/tapbundle';
import * as fs from 'fs/promises';
import * as path from 'path';
import { execSync } from 'child_process';

// Master test for corpus testing
tap.test('Run all corpus tests', async () => {
  console.log('Running all corpus tests...');

  // Create output directory
  const testDir = path.join(process.cwd(), 'test', 'output');
  await fs.mkdir(testDir, { recursive: true });

  // Run each test file and collect results
  const testFiles = [
    'test.zugferd-corpus.ts',
    'test.xml-rechnung-corpus.ts',
    // 'test.validation-corpus.ts', // Skip this test for now as it has issues
    'test.circular-corpus.ts'
  ];

  const results: Record<string, any> = {};

  for (const testFile of testFiles) {
    console.log(`Running ${testFile}...`);

    try {
      // Run the test
      execSync(`tsx test/${testFile}`, { stdio: 'inherit' });

      // Read the results
      const resultFile = testFile.replace('.ts', '-results.json');
      const resultPath = path.join(testDir, resultFile);

      if (await fileExists(resultPath)) {
        const resultContent = await fs.readFile(resultPath, 'utf8');
        results[testFile] = JSON.parse(resultContent);
      } else {
        results[testFile] = { error: 'No results file found' };
      }
    } catch (error) {
      console.error(`Error running ${testFile}:`, error);
      results[testFile] = { error: error.message };
    }
  }

  // Save the combined results
  await fs.writeFile(
    path.join(testDir, 'corpus-master-results.json'),
    JSON.stringify(results, null, 2)
  );

  // Generate a summary report
  const summary = generateSummary(results);
  await fs.writeFile(
    path.join(testDir, 'corpus-summary.md'),
    summary
  );

  console.log('All corpus tests completed.');
});

/**
 * Generates a summary report from the test results
 * @param results Test results
 * @returns Summary report in Markdown format
 */
function generateSummary(results: Record<string, any>): string {
  let summary = '# XInvoice Corpus Testing Summary\n\n';

  // Add date and time
  summary += `Generated on: ${new Date().toISOString()}\n\n`;

  // Add overall summary
  summary += '## Overall Summary\n\n';
  summary += '| Test | Success Rate | Files Tested |\n';
  summary += '|------|--------------|-------------|\n';

  for (const [testFile, result] of Object.entries(results)) {
    if (result.error) {
      summary += `| ${testFile} | Error: ${result.error} | N/A |\n`;
      continue;
    }

    let successRate = 'N/A';
    let filesTested = 'N/A';

    if (testFile === 'test.zugferd-corpus.ts') {
      const rate = result.totalCorrectSuccessRate * 100;
      successRate = `${rate.toFixed(2)}%`;

      const v1Correct = result.zugferdV1Correct?.success + result.zugferdV1Correct?.fail || 0;
      const v1Fail = result.zugferdV1Fail?.success + result.zugferdV1Fail?.fail || 0;
      const v2Correct = result.zugferdV2Correct?.success + result.zugferdV2Correct?.fail || 0;
      const v2Fail = result.zugferdV2Fail?.success + result.zugferdV2Fail?.fail || 0;

      filesTested = `${v1Correct + v1Fail + v2Correct + v2Fail}`;
    } else if (testFile === 'test.xml-rechnung-corpus.ts') {
      const rate = result.totalSuccessRate * 100;
      successRate = `${rate.toFixed(2)}%`;

      const cii = result.cii?.success + result.cii?.fail || 0;
      const ubl = result.ubl?.success + result.ubl?.fail || 0;
      const fx = result.fx?.success + result.fx?.fail || 0;

      filesTested = `${cii + ubl + fx}`;
    } else if (testFile === 'test.other-formats-corpus.ts') {
      const rate = result.totalSuccessRate * 100;
      successRate = `${rate.toFixed(2)}%`;

      const peppol = result.peppol?.success + result.peppol?.fail || 0;
      const fatturapa = result.fatturapa?.success + result.fatturapa?.fail || 0;

      filesTested = `${peppol + fatturapa}`;
    } else if (testFile === 'test.validation-corpus.ts') {
      const rate = result.totalCorrectSuccessRate * 100;
      successRate = `${rate.toFixed(2)}%`;

      const zugferdV2Correct = result.zugferdV2Correct?.success + result.zugferdV2Correct?.fail || 0;
      const zugferdV2Fail = result.zugferdV2Fail?.success + result.zugferdV2Fail?.fail || 0;
      const cii = result.cii?.success + result.cii?.fail || 0;
      const ubl = result.ubl?.success + result.ubl?.fail || 0;

      filesTested = `${zugferdV2Correct + zugferdV2Fail + cii + ubl}`;
    } else if (testFile === 'test.circular-corpus.ts') {
      const rate = result.totalSuccessRate * 100;
      successRate = `${rate.toFixed(2)}%`;

      const cii = result.cii?.success + result.cii?.fail || 0;
      const ubl = result.ubl?.success + result.ubl?.fail || 0;

      filesTested = `${cii + ubl}`;
    }

    summary += `| ${testFile} | ${successRate} | ${filesTested} |\n`;
  }

  // Add detailed results for each test
  for (const [testFile, result] of Object.entries(results)) {
    if (result.error) {
      continue;
    }

    summary += `\n## ${testFile}\n\n`;

    if (testFile === 'test.zugferd-corpus.ts') {
      summary += '### ZUGFeRD v1 Correct Files\n\n';
      summary += `Success: ${result.zugferdV1Correct?.success || 0}, Fail: ${result.zugferdV1Correct?.fail || 0}\n\n`;

      summary += '### ZUGFeRD v1 Fail Files\n\n';
      summary += `Success: ${result.zugferdV1Fail?.success || 0}, Fail: ${result.zugferdV1Fail?.fail || 0}\n\n`;

      summary += '### ZUGFeRD v2 Correct Files\n\n';
      summary += `Success: ${result.zugferdV2Correct?.success || 0}, Fail: ${result.zugferdV2Correct?.fail || 0}\n\n`;

      summary += '### ZUGFeRD v2 Fail Files\n\n';
      summary += `Success: ${result.zugferdV2Fail?.success || 0}, Fail: ${result.zugferdV2Fail?.fail || 0}\n\n`;
    } else if (testFile === 'test.xml-rechnung-corpus.ts') {
      summary += '### CII Files\n\n';
      summary += `Success: ${result.cii?.success || 0}, Fail: ${result.cii?.fail || 0}\n\n`;

      summary += '### UBL Files\n\n';
      summary += `Success: ${result.ubl?.success || 0}, Fail: ${result.ubl?.fail || 0}\n\n`;

      summary += '### FX Files\n\n';
      summary += `Success: ${result.fx?.success || 0}, Fail: ${result.fx?.fail || 0}\n\n`;
    } else if (testFile === 'test.other-formats-corpus.ts') {
      summary += '### PEPPOL Files\n\n';
      summary += `Success: ${result.peppol?.success || 0}, Fail: ${result.peppol?.fail || 0}\n\n`;

      summary += '### fatturaPA Files\n\n';
      summary += `Success: ${result.fatturapa?.success || 0}, Fail: ${result.fatturapa?.fail || 0}\n\n`;
    } else if (testFile === 'test.validation-corpus.ts') {
      summary += '### ZUGFeRD v2 Correct Files Validation\n\n';
      summary += `Success: ${result.zugferdV2Correct?.success || 0}, Fail: ${result.zugferdV2Correct?.fail || 0}\n\n`;

      summary += '### ZUGFeRD v2 Fail Files Validation\n\n';
      summary += `Success: ${result.zugferdV2Fail?.success || 0}, Fail: ${result.zugferdV2Fail?.fail || 0}\n\n`;

      summary += '### CII Files Validation\n\n';
      summary += `Success: ${result.cii?.success || 0}, Fail: ${result.cii?.fail || 0}\n\n`;

      summary += '### UBL Files Validation\n\n';
      summary += `Success: ${result.ubl?.success || 0}, Fail: ${result.ubl?.fail || 0}\n\n`;
    } else if (testFile === 'test.circular-corpus.ts') {
      summary += '### CII Files Circular Testing\n\n';
      summary += `Success: ${result.cii?.success || 0}, Fail: ${result.cii?.fail || 0}\n\n`;

      summary += '### UBL Files Circular Testing\n\n';
      summary += `Success: ${result.ubl?.success || 0}, Fail: ${result.ubl?.fail || 0}\n\n`;
    }
  }

  return summary;
}

/**
 * Checks if a file exists
 * @param filePath Path to the file
 * @returns True if the file exists
 */
async function fileExists(filePath: string): Promise<boolean> {
  try {
    await fs.access(filePath);
    return true;
  } catch {
    return false;
  }
}

// Run the tests
tap.start();