#!/usr/bin/env bun
import { Command } from 'commander';
import { existsSync } from 'fs';
import { resolve } from 'path';
import chalk from 'chalk';
import { loadConfig } from './config';
import { CoverageRunner } from './runner';
import { CoverageProcessor } from './processor';
import { ReporterManager } from './reporters';
import type { CLIOptions } from './types';

const program = new Command();

program
  .name('stock-bot-coverage')
  .description('Advanced coverage tool for Stock Bot with exclusion support and beautiful reporting')
  .version('1.0.0')
  .option('-p, --packages <packages...>', 'Run coverage for specific packages')
  .option('-e, --exclude <patterns...>', 'Glob patterns to exclude from coverage')
  .option('-i, --include <patterns...>', 'Glob patterns to include in coverage')
  .option('-r, --reporters <reporters...>', 'Coverage reporters (terminal, html, json, markdown, text)')
  .option('-t, --threshold <number>', 'Set coverage threshold for all metrics', parseFloat)
  .option('--threshold-lines <number>', 'Set line coverage threshold', parseFloat)
  .option('--threshold-functions <number>', 'Set function coverage threshold', parseFloat)
  .option('--threshold-branches <number>', 'Set branch coverage threshold', parseFloat)
  .option('--threshold-statements <number>', 'Set statement coverage threshold', parseFloat)
  .option('-o, --output-dir <path>', 'Output directory for reports')
  .option('-c, --config <path>', 'Path to coverage config file')
  .option('--fail-under', 'Exit with non-zero code if coverage is below threshold')
  .action(async (options: CLIOptions) => {
    try {
      console.log(chalk.bold.blue('\n🚀 Stock Bot Coverage Tool\n'));

      // Load configuration
      const config = loadConfig(options);
      console.log(chalk.gray('Configuration loaded'));
      console.log(chalk.gray(`Workspace root: ${config.workspaceRoot}`));
      console.log(chalk.gray(`Excluded patterns: ${config.exclude.length}`));
      console.log(chalk.gray(`Reporters: ${config.reporters.join(', ')}\n`));

      // Run coverage
      const runner = new CoverageRunner(config);
      console.log(chalk.yellow('Running tests with coverage...\n'));
      
      const result = await runner.run();
      
      if (!result.success) {
        console.error(chalk.red('\n❌ Some tests failed'));
        if (options.failUnder) {
          process.exit(1);
        }
      }

      // Process coverage data
      const processor = new CoverageProcessor(config);
      const report = processor.process(result.coverage, result.testResults);

      // Generate reports
      console.log(chalk.yellow('\nGenerating reports...\n'));
      const reporterManager = new ReporterManager();
      await reporterManager.report(report, config.reporters, config.outputDir);

      // Check thresholds
      if (options.failUnder) {
        const thresholdResult = processor.checkThresholds(report);
        if (!thresholdResult.passed) {
          console.error(chalk.red('\n❌ Coverage thresholds not met'));
          for (const failure of thresholdResult.failures) {
            console.error(
              chalk.red(
                `  ${failure.metric}: ${failure.actual.toFixed(1)}% < ${failure.expected}%`
              )
            );
          }
          process.exit(1);
        }
      }

      console.log(chalk.green('\n✅ Coverage analysis complete!\n'));
    } catch (error) {
      console.error(chalk.red('\n❌ Error running coverage:'), error);
      process.exit(1);
    }
  });

// Add init command to create default config
program
  .command('init')
  .description('Create a default .coveragerc.json configuration file')
  .action(() => {
    const configPath = resolve(process.cwd(), '.coveragerc.json');
    
    if (existsSync(configPath)) {
      console.error(chalk.red('Configuration file already exists'));
      process.exit(1);
    }

    const defaultConfig = {
      exclude: [
        '**/node_modules/**',
        '**/dist/**',
        '**/build/**',
        '**/coverage/**',
        '**/*.test.ts',
        '**/*.test.js',
        '**/*.spec.ts',
        '**/*.spec.js',
        '**/test/**',
        '**/tests/**',
        '**/__tests__/**',
        '**/__mocks__/**',
      ],
      reporters: ['terminal', 'html'],
      thresholds: {
        lines: 80,
        functions: 80,
        branches: 80,
        statements: 80,
      },
      outputDir: 'coverage',
    };

    require('fs').writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
    console.log(chalk.green(`✅ Created ${configPath}`));
  });

program.parse();