/**
 * validate-blazor-state command
 *
 * Validates Blazor Server session state patterns.
 * Ensures proper Persist + Reload pattern implementation.
 *
 * Usage:
 *   morph-spec validate-blazor-state [path]
 *   morph-spec validate-blazor-state src/ --verbose
 */

import { glob } from 'glob';
import { readFileSync, existsSync, statSync } from 'fs';
import { join, resolve } from 'path';
import chalk from 'chalk';
import ora from 'ora';

import {
  validateBlazorState,
} from '../../lib/validators/blazor/blazor-state-validator.js';
import { countIssues } from '../../lib/validators/shared/index.js';

/**
 * Main command handler for validate-blazor-state.
 *
 * @param {string} [targetPath] - Path to validate (file or directory)
 * @param {Object} options - Command options
 * @param {boolean} [options.verbose] - Show detailed output
 */
export async function validateBlazorStateCommand(targetPath, options = {}) {
  const { verbose = false } = options;

  console.log('');
  console.log(
    chalk.cyan('\uD83D\uDD0D Validando padroes de SessionState em Blazor Server...')
  );
  console.log('');

  // Determine target path
  const basePath = targetPath ? resolve(targetPath) : process.cwd();

  if (!existsSync(basePath)) {
    console.log(chalk.red(`\u274C Path not found: ${basePath}`));
    process.exit(1);
  }

  const spinner = ora('Scanning for C# and Razor files...').start();

  let files = [];

  try {
    const stats = statSync(basePath);

    if (stats.isFile()) {
      if (basePath.endsWith('.cs') || basePath.endsWith('.razor')) {
        files = [basePath];
      } else {
        spinner.fail('File must be .cs or .razor');
        process.exit(1);
      }
    } else {
      // Find all relevant files
      const pattern = join(basePath, '**/*.{cs,razor}');
      files = await glob(pattern, {
        ignore: [
          '**/node_modules/**',
          '**/bin/**',
          '**/obj/**',
          '**/Migrations/**',
        ],
        windowsPathsNoEscape: true,
      });
    }

    spinner.succeed(`Found ${files.length} file(s)`);
  } catch (error) {
    spinner.fail(`Error scanning files: ${error.message}`);
    process.exit(1);
  }

  if (files.length === 0) {
    console.log(chalk.yellow('\n\u26A0\uFE0F No files found to validate'));
    return;
  }

  // Validate each file
  const allIssues = [];
  const fileResults = [];

  for (const file of files) {
    try {
      const content = readFileSync(file, 'utf-8');
      const issues = validateBlazorState(content, file);

      if (issues.length > 0) {
        allIssues.push(...issues);
        fileResults.push({ file, issues });
      }
    } catch (error) {
      if (verbose) {
        console.log(chalk.red(`\u274C Error reading ${file}: ${error.message}`));
      }
    }
  }

  // Output results
  console.log('');

  if (allIssues.length === 0) {
    console.log(
      chalk.green('\u2705 Padroes de SessionState validados com sucesso!')
    );
    console.log(
      chalk.gray(
        '   Dica: Certifique-se de sempre verificar IsLoaded em OnInitializedAsync.'
      )
    );
    console.log('');
    return;
  }

  // Display issues
  if (verbose) {
    fileResults.forEach(({ file, issues }) => {
      console.log(chalk.white.bold(`\n${file}`));
      console.log(chalk.gray('-'.repeat(60)));

      issues.forEach((issue) => {
        const icon =
          issue.type === 'error'
            ? '\u274C'
            : issue.type === 'warning'
            ? '\u26A0\uFE0F'
            : '\u2139\uFE0F';

        const color =
          issue.type === 'error'
            ? chalk.red
            : issue.type === 'warning'
            ? chalk.yellow
            : chalk.blue;

        console.log(`${icon} ${color(issue.message)}`);
        if (issue.suggestion) {
          console.log(chalk.gray(`   \u2192 ${issue.suggestion}`));
        }
        if (issue.line) {
          console.log(chalk.dim(`   Linha: ${issue.line}`));
        }
        console.log('');
      });
    });
  } else {
    allIssues.forEach((issue) => {
      const icon =
        issue.type === 'error'
          ? '\u274C'
          : issue.type === 'warning'
          ? '\u26A0\uFE0F'
          : '\u2139\uFE0F';

      const color =
        issue.type === 'error'
          ? chalk.red
          : issue.type === 'warning'
          ? chalk.yellow
          : chalk.blue;

      console.log(`${icon} ${color(issue.message)}`);
      if (issue.suggestion) {
        console.log(chalk.gray(`   \u2192 ${issue.suggestion}`));
      }
      console.log(chalk.dim(`   ${issue.file}`));
      console.log('');
    });
  }

  // Summary
  const { errors, warnings, infos } = countIssues(allIssues);
  const summaryColor = errors > 0 ? chalk.red : chalk.yellow;

  console.log(chalk.gray('-'.repeat(60)));
  console.log(
    summaryColor(
      `\n${files.length} arquivo(s) validado(s) | ${errors} erro(s) | ${warnings} warning(s) | ${infos} info(s)\n`
    )
  );

  // Checklist reminder
  console.log(chalk.cyan('\uD83D\uDCCB Checklist SessionState:'));
  console.log(chalk.gray('   [ ] SessionState tem LoadFrom(entity)?'));
  console.log(chalk.gray('   [ ] SessionState tem propriedade IsLoaded?'));
  console.log(chalk.gray('   [ ] Paginas verificam IsLoaded em OnInitializedAsync?'));
  console.log(chalk.gray('   [ ] SessionMiddleware configurado em Program.cs?'));
  console.log(chalk.gray('   [ ] IHttpContextAccessor registrado?'));
  console.log('');

  // Recommendation
  if (errors > 0) {
    console.log(
      chalk.cyan(
        '\uD83D\uDCD6 Consulte: framework/standards/frontend/blazor/state.md para o padrao completo'
      )
    );
    console.log('');
    process.exit(1);
  }
}

export default validateBlazorStateCommand;
