#!/usr/bin/env node

/**
 * Validation CLI
 *
 * Runs all validators (package, architecture, contrast) on the project.
 * Part of Sprint 4: Continuous Validation + Learning System
 *
 * Usage:
 *   morph-spec validate [options]
 *   morph-spec validate packages
 *   morph-spec validate architecture
 *   morph-spec validate contrast
 *   morph-spec validate all
 *
 * MORPH-SPEC 3.0
 */

import chalk from 'chalk';
import { validatePackages } from '../src/lib/validators/package-validator.js';
import { validateArchitecture } from '../src/lib/validators/architecture-validator.js';
import { validateContrast } from '../src/lib/validators/ui-contrast-validator.js';
import { LearningSystem } from '../src/lib/learning-system.js';

const VALIDATORS = {
  packages: {
    name: 'Package Compatibility',
    description: 'Validates NuGet package versions against .NET compatibility matrix',
    run: validatePackages
  },
  architecture: {
    name: 'Architecture Patterns',
    description: 'Detects DI anti-patterns and lifecycle issues in Blazor',
    run: validateArchitecture
  },
  contrast: {
    name: 'UI Contrast (WCAG)',
    description: 'Validates color contrast ratios for accessibility',
    run: validateContrast
  }
};

/**
 * Main validation command
 */
export async function validateCommand(args = []) {
  const validatorName = args[0] || 'all';
  const options = parseOptions(args);

  console.log(chalk.bold.cyan('\n🔍 MORPH-SPEC Validator\n'));

  if (validatorName === 'all') {
    await runAllValidators(options);
  } else if (VALIDATORS[validatorName]) {
    await runValidator(validatorName, options);
  } else {
    console.error(chalk.red(`❌ Unknown validator: ${validatorName}`));
    console.log(chalk.gray('\nAvailable validators:'));
    for (const [name, validator] of Object.entries(VALIDATORS)) {
      console.log(chalk.gray(`  - ${name}: ${validator.description}`));
    }
    console.log(chalk.gray('  - all: Run all validators'));
    process.exit(1);
  }

  // Show learning insights if --insights flag
  if (options.insights) {
    await showLearningInsights(options);
  }
}

/**
 * Run all validators
 */
async function runAllValidators(options) {
  const results = {};
  let totalErrors = 0;
  let totalWarnings = 0;

  console.log(chalk.gray('Running all validators...\n'));

  for (const [name, validator] of Object.entries(VALIDATORS)) {
    console.log(chalk.cyan(`\n▸ ${validator.name}`));
    console.log(chalk.gray(`  ${validator.description}\n`));

    try {
      const result = await validator.run('.', {
        verbose: options.verbose,
        autoFix: options.autoFix
      });

      results[name] = result;

      // Count errors/warnings
      if (result.errors !== undefined) {
        totalErrors += result.errors;
        totalWarnings += result.warnings || 0;
      } else if (result.results) {
        // Count issues in results array
        const issues = result.results.flatMap(r => r.issues || []);
        totalErrors += issues.filter(i => i.level === 'error').length;
        totalWarnings += issues.filter(i => i.level === 'warning').length;
      }

    } catch (error) {
      console.error(chalk.red(`  ❌ Failed: ${error.message}`));
      results[name] = { status: 'error', error: error.message };
    }
  }

  // Summary
  console.log(chalk.bold.cyan('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
  console.log(chalk.bold('📊 Validation Summary\n'));

  if (totalErrors === 0 && totalWarnings === 0) {
    console.log(chalk.green('✅ All validations passed!'));
  } else {
    if (totalErrors > 0) {
      console.log(chalk.red(`❌ ${totalErrors} error(s) found`));
    }
    if (totalWarnings > 0) {
      console.log(chalk.yellow(`⚠️  ${totalWarnings} warning(s) found`));
    }
  }

  console.log('');

  // Exit with error code if errors found
  if (totalErrors > 0 && !options.noFail) {
    process.exit(1);
  }
}

/**
 * Run single validator
 */
async function runValidator(name, options) {
  const validator = VALIDATORS[name];

  console.log(chalk.cyan(`▸ ${validator.name}`));
  console.log(chalk.gray(`  ${validator.description}\n`));

  try {
    const result = await validator.run('.', {
      verbose: true, // Always verbose for single validator
      autoFix: options.autoFix,
      wcagLevel: options.wcagLevel
    });

    if (result.status === 'ok') {
      console.log(chalk.green('\n✅ Validation passed!\n'));
    } else {
      console.log(chalk.yellow('\n⚠️  Validation completed with issues\n'));

      if (result.errors > 0 && !options.noFail) {
        process.exit(1);
      }
    }

  } catch (error) {
    console.error(chalk.red(`\n❌ Validation failed: ${error.message}\n`));
    if (!options.noFail) {
      process.exit(1);
    }
  }
}

/**
 * Show learning insights
 */
async function showLearningInsights(options) {
  console.log(chalk.bold.cyan('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));

  const learner = new LearningSystem('.');
  learner.formatInsights();

  if (options.verbose) {
    const suggestions = learner.getAllSuggestions();
    learner.formatSuggestions(suggestions);
  }
}

/**
 * Parse command-line options
 */
function parseOptions(args) {
  const options = {
    verbose: false,
    autoFix: false,
    noFail: false,
    insights: false,
    wcagLevel: 'AA'
  };

  for (const arg of args) {
    if (arg === '--verbose' || arg === '-v') {
      options.verbose = true;
    } else if (arg === '--auto-fix' || arg === '--fix') {
      options.autoFix = true;
    } else if (arg === '--no-fail') {
      options.noFail = true;
    } else if (arg === '--insights' || arg === '-i') {
      options.insights = true;
    } else if (arg === '--wcag-aaa') {
      options.wcagLevel = 'AAA';
    }
  }

  return options;
}

/**
 * Show help
 */
export function showValidateHelp() {
  console.log(`
${chalk.bold.cyan('morph-spec validate')} - Run project validations

${chalk.bold('USAGE')}
  morph-spec validate [validator] [options]

${chalk.bold('VALIDATORS')}
  all             Run all validators (default)
  packages        Validate NuGet package compatibility (.NET 10)
  architecture    Validate architecture patterns (DI, lifecycle)
  contrast        Validate UI contrast ratios (WCAG 2.1)

${chalk.bold('OPTIONS')}
  --verbose, -v        Show detailed output
  --auto-fix, --fix    Auto-fix issues where possible
  --no-fail            Don't exit with error code
  --insights, -i       Show learning insights
  --wcag-aaa           Use WCAG AAA standard (stricter)

${chalk.bold('EXAMPLES')}
  morph-spec validate                    # Run all validators
  morph-spec validate packages --fix     # Validate packages and auto-fix
  morph-spec validate architecture -v    # Verbose architecture validation
  morph-spec validate contrast --wcag-aaa # Stricter contrast validation
  morph-spec validate all --insights     # All validators + AI insights

${chalk.bold('EXIT CODES')}
  0    All validations passed
  1    Validation errors found (unless --no-fail)

${chalk.bold('INTEGRATION')}
  Add to pre-commit hook:
    morph-spec validate --no-fail

  CI/CD pipeline:
    morph-spec validate || exit 1
`);
}

// Run if called directly
if (import.meta.url === `file://${process.argv[1]}`) {
  const args = process.argv.slice(2);

  if (args.includes('--help') || args.includes('-h')) {
    showValidateHelp();
    process.exit(0);
  }

  validateCommand(args).catch(error => {
    console.error(chalk.red(`\n❌ Error: ${error.message}\n`));
    process.exit(1);
  });
}
