#!/usr/bin/env node

try {
  // Import the required modules
  const { Command } = require('commander');
  const chalk = require('chalk');
  const fs = require('fs');
  const path = require('path');
  
  // Import the CodeAnalyzer class
  const { CodeAnalyzer, SeverityLevel, CategoryType } = require('../dist/index');
  
  // Create a new command
  const command = new Command('analyze-code');
  
  // Configure the command
  command
    .description('Analyze code for potential issues, bugs, and improvements')
    .argument('<patterns...>', 'File patterns to analyze (e.g., "src/**/*.js")')
    .option('--severity <level>', 'Minimum severity level to report (info, warning, error, critical)', 'info')
    .option('--category <categories>', 'Categories to include (comma-separated: performance, security, maintainability, bugs, style)')
    .option('--ignore <pattern>', 'Files to ignore (comma-separated)')
    .option('--max-depth <depth>', 'Maximum depth for recursive analysis', parseInt)
    .option('--root-dir <path>', 'Root directory for analysis')
    .option('--output <path>', 'Write report to file (json or html)')
    .option('--format <format>', 'Output format (text, json, html)', 'text')
    .option('--silent', 'Suppress output', false)
    .action(async (patterns, options) => {
      try {
        // Parse severity level
        const severityLevel = parseSeverityLevel(options.severity);
        
        // Parse categories if provided
        const categories = options.category ? parseCategories(options.category) : undefined;
        
        // Parse ignore patterns if provided
        const ignorePatterns = options.ignore ? parseList(options.ignore) : undefined;
        
        // Create analyzer
        const analyzer = new CodeAnalyzer({
          minSeverity: severityLevel,
          categories: categories,
          ignore: ignorePatterns,
          maxDepth: options.maxDepth,
          rootDir: options.rootDir,
          dryRun: options.dryRun
        });
        
        // Start processing
        if (!options.silent) {
          console.log(chalk.cyan('⠋ Analyzing code...'));
        }
        
        // Process files
        const results = await analyzer.analyzeFiles(patterns);
        
        // Count findings
        const totalFindings = results.reduce(
          (sum, result) => sum + result.findings.length,
          0
        );
        
        // Log results
        if (!options.silent) {
          console.log(chalk.green(`✓ Analyzed ${results.length} files, found ${totalFindings} issues`));
          
          // Show detailed results
          const successResults = results.filter(r => r.success);
          const errorResults = results.filter(r => !r.success);
          
          // Log errors first
          if (errorResults.length > 0) {
            console.log('\n' + chalk.bold('Errors:'));
            errorResults.forEach(result => {
              console.log(chalk.red(`Failed to analyze ${result.filePath}: ${result.error}`));
            });
          }
          
          // Log findings
          if (totalFindings > 0) {
            console.log('\n' + chalk.bold('Findings:'));
            
            // Group findings by file
            const findingsByFile = {};
            
            successResults.forEach(result => {
              if (result.findings.length > 0) {
                findingsByFile[result.filePath] = result.findings;
              }
            });
            
            // Display findings
            Object.entries(findingsByFile).forEach(([filePath, findings]) => {
              console.log(`\n${chalk.underline(filePath)}`);
              
              // Sort findings by line number
              findings.sort((a, b) => a.line - b.line);
              
              findings.forEach(finding => {
                // Format severity with color
                let severityColor;
                switch (finding.severity) {
                  case SeverityLevel.Critical:
                    severityColor = chalk.bgRed.white;
                    break;
                  case SeverityLevel.Error:
                    severityColor = chalk.red;
                    break;
                  case SeverityLevel.Warning:
                    severityColor = chalk.yellow;
                    break;
                  default:
                    severityColor = chalk.blue;
                }
                
                // Format category with color
                let categoryColor;
                switch (finding.category) {
                  case CategoryType.Performance:
                    categoryColor = chalk.magenta;
                    break;
                  case CategoryType.Security:
                    categoryColor = chalk.red;
                    break;
                  case CategoryType.Maintainability:
                    categoryColor = chalk.cyan;
                    break;
                  case CategoryType.Bugs:
                    categoryColor = chalk.yellow;
                    break;
                  default:
                    categoryColor = chalk.gray;
                }
                
                // Log finding header
                console.log(
                  `  ${severityColor(finding.severity.toUpperCase())} ` +
                  `${categoryColor(`[${finding.category}]`)} ` +
                  `Line ${finding.line}${finding.column ? `:${finding.column}` : ''}: ` +
                  `${finding.message}`
                );
                
                // Log code snippet
                console.log('');
                console.log(chalk.gray('  │ ' + finding.code.replace(/\n/g, '\n  │ ')));
                console.log('');
                
                // Log explanation
                console.log(chalk.gray('  ' + finding.explanation));
                console.log('');
              });
            });
          }
          
          // Generate summary
          console.log('\n' + chalk.bold('Summary:'));
          
          // Count by severity
          const severityCounts = {
            [SeverityLevel.Info]: 0,
            [SeverityLevel.Warning]: 0,
            [SeverityLevel.Error]: 0,
            [SeverityLevel.Critical]: 0
          };
          
          // Count by category
          const categoryCounts = {
            [CategoryType.Performance]: 0,
            [CategoryType.Security]: 0,
            [CategoryType.Maintainability]: 0,
            [CategoryType.Bugs]: 0,
            [CategoryType.Style]: 0
          };
          
          // Count findings
          successResults.forEach(result => {
            result.findings.forEach(finding => {
              severityCounts[finding.severity]++;
              categoryCounts[finding.category]++;
            });
          });
          
          // Log severity counts
          console.log('  Severity:');
          console.log(`    ${chalk.red('Critical')}: ${severityCounts[SeverityLevel.Critical]}`);
          console.log(`    ${chalk.red('Error')}: ${severityCounts[SeverityLevel.Error]}`);
          console.log(`    ${chalk.yellow('Warning')}: ${severityCounts[SeverityLevel.Warning]}`);
          console.log(`    ${chalk.blue('Info')}: ${severityCounts[SeverityLevel.Info]}`);
          
          // Log category counts
          console.log('  Category:');
          console.log(`    ${chalk.magenta('Performance')}: ${categoryCounts[CategoryType.Performance]}`);
          console.log(`    ${chalk.red('Security')}: ${categoryCounts[CategoryType.Security]}`);
          console.log(`    ${chalk.cyan('Maintainability')}: ${categoryCounts[CategoryType.Maintainability]}`);
          console.log(`    ${chalk.yellow('Bugs')}: ${categoryCounts[CategoryType.Bugs]}`);
          console.log(`    ${chalk.gray('Style')}: ${categoryCounts[CategoryType.Style]}`);
        }
      } catch (error) {
        console.error(chalk.red('✗ ' + error.message));
        process.exit(1);
      }
    });
  
  // Parse command line arguments
  command.parse(process.argv);
  
  // Helper functions
  
  /**
   * Parse a comma-separated list
   *
   * @param {string} value - Comma-separated string
   * @returns {string[]} Array of strings
   */
  function parseList(value) {
    return value.split(',').map(item => item.trim());
  }
  
  /**
   * Parse categories from a comma-separated list
   *
   * @param {string} value - Comma-separated string
   * @returns {string[]} Array of categories
   */
  function parseCategories(value) {
    const categories = value.split(',').map(item => item.trim().toLowerCase());
    
    return categories.map(category => {
      switch (category) {
        case 'performance':
          return CategoryType.Performance;
        case 'security':
          return CategoryType.Security;
        case 'maintainability':
          return CategoryType.Maintainability;
        case 'bugs':
          return CategoryType.Bugs;
        case 'style':
          return CategoryType.Style;
        default:
          throw new Error(`Invalid category: ${category}`);
      }
    });
  }
  
  /**
   * Parse severity level from string
   *
   * @param {string} value - Severity level string
   * @returns {string} Severity level enum
   */
  function parseSeverityLevel(value) {
    switch (value.toLowerCase()) {
      case 'info':
        return SeverityLevel.Info;
      case 'warning':
        return SeverityLevel.Warning;
      case 'error':
        return SeverityLevel.Error;
      case 'critical':
        return SeverityLevel.Critical;
      default:
        throw new Error(`Invalid severity level: ${value}`);
    }
  }
} catch (error) {
  console.error('Error executing command:', error.message);
  process.exit(1);
}
