#!/usr/bin/env node

/**
 * 颜色验证脚本
 *
 * 检查组件文件中是否还有硬编码的十六进制颜色值
 * 用法: node scripts/validate-colors.js
 */

const fs = require('fs');
const path = require('path');

// 硬编码颜色的正则模式
const hardcodedColorPatterns = [
  // Tailwind 类名中的十六进制颜色: bg-[#hex], text-[#hex], border-[#hex]
  /(bg|text|border|from|to|via)-\[#[0-9a-fA-F]{3,8}\]/g,

  // 内联样式中的十六进制颜色
  /(?:background|color|border)(?:Color)?:\s*['"]?#[0-9a-fA-F]{3,8}/g,

  // 对象样式中的十六进制颜色
  /['"](?:background|color|border)(?:Color)?['"]\s*:\s*['"]#[0-9a-fA-F]{3,8}/g,
];

// 允许的例外情况（特殊设计需求）
const allowedExceptions = [
  // rgba/hsla 透明度值（毛玻璃效果等）
  /rgba?\(/,
  /hsla?\(/,

  // 渐变色（gradient-to-br from-green-400 to-emerald-500 等非硬编码）
  // 注意：这里不排除硬编码的渐变，会被上面的模式捕获
];

// 需要检查的目录
const componentsDir = path.join(__dirname, '../components');

// 收集结果
const results = {
  files: [],
  totalViolations: 0,
};

/**
 * 检查单个文件
 */
function checkFile(filePath) {
  const content = fs.readFileSync(filePath, 'utf-8');
  const violations = [];

  // 按行分析
  const lines = content.split('\n');

  lines.forEach((line, index) => {
    hardcodedColorPatterns.forEach(pattern => {
      const matches = line.match(pattern);
      if (matches) {
        // 检查是否是允许的例外
        const isException = allowedExceptions.some(exceptionPattern =>
          exceptionPattern.test(line)
        );

        if (!isException) {
          matches.forEach(match => {
            violations.push({
              line: index + 1,
              content: line.trim(),
              match: match,
            });
          });
        }
      }
    });
  });

  if (violations.length > 0) {
    results.files.push({
      path: path.relative(process.cwd(), filePath),
      violations: violations,
      count: violations.length,
    });
    results.totalViolations += violations.length;
  }

  return violations.length === 0;
}

/**
 * 递归扫描目录
 */
function scanDirectory(dir) {
  const entries = fs.readdirSync(dir, { withFileTypes: true });

  entries.forEach(entry => {
    const fullPath = path.join(dir, entry.name);

    if (entry.isDirectory()) {
      scanDirectory(fullPath);
    } else if (entry.isFile() && /\.(tsx|ts|jsx|js)$/.test(entry.name)) {
      checkFile(fullPath);
    }
  });
}

/**
 * 打印结果
 */
function printResults() {
  console.log('\n='.repeat(80));
  console.log('🎨 设计系统颜色验证报告');
  console.log('='.repeat(80));
  console.log();

  if (results.totalViolations === 0) {
    console.log('✅ 太棒了！没有发现硬编码颜色值。');
    console.log();
    console.log('所有组件都已成功迁移到设计系统！');
  } else {
    console.log(`⚠️  发现 ${results.totalViolations} 处硬编码颜色值，分布在 ${results.files.length} 个文件中：`);
    console.log();

    results.files.forEach(file => {
      console.log(`📄 ${file.path} (${file.count} 处问题)`);
      console.log('─'.repeat(80));

      // 按行号分组相同的问题
      const lineMap = new Map();
      file.violations.forEach(v => {
        if (!lineMap.has(v.line)) {
          lineMap.set(v.line, []);
        }
        lineMap.get(v.line).push(v.match);
      });

      lineMap.forEach((matches, lineNum) => {
        const firstViolation = file.violations.find(v => v.line === lineNum);
        console.log(`  行 ${lineNum}: ${firstViolation.content.substring(0, 100)}${firstViolation.content.length > 100 ? '...' : ''}`);
        matches.forEach(match => {
          console.log(`           ↳ ${match}`);
        });
      });

      console.log();
    });

    console.log('='.repeat(80));
    console.log('💡 建议：');
    console.log('  • 将硬编码颜色替换为设计系统的 token (如 text-text-primary, bg-bg-base 等)');
    console.log('  • 检查是否有特殊设计需求需要保留硬编码');
    console.log('  • 参考 /styles/design-system.css 中定义的颜色变量');
  }

  console.log('='.repeat(80));
  console.log();

  // 退出码
  process.exit(results.totalViolations > 0 ? 1 : 0);
}

// 执行扫描
console.log('🔍 正在扫描组件文件...');
scanDirectory(componentsDir);
printResults();
