import fs from 'node:fs';
import path from 'node:path';

export const DEFAULT_SCAN_DIR_CANDIDATES = ['src', 'app', 'pages', 'components'];
export const DEFAULT_SCAN_EXTS = new Set(['.js', '.jsx', '.ts', '.tsx', '.css']);

export function exists(p) {
  try {
    fs.accessSync(p);
    return true;
  } catch {
    return false;
  }
}

export function read(p) {
  try {
    return fs.readFileSync(p, 'utf8');
  } catch {
    return null;
  }
}

export function rel(projectRoot, p) {
  return path.relative(projectRoot, p) || p;
}

export function walk(dir, out) {
  const ents = fs.readdirSync(dir, { withFileTypes: true });
  for (const e of ents) {
    if (e.name === 'node_modules' || e.name.startsWith('.')) continue;
    const p = path.join(dir, e.name);
    if (e.isDirectory()) walk(p, out);
    else if (e.isFile()) out.push(p);
  }
}

/**
 * @param {string} projectRoot
 * @param {string[]} [scanDirCandidates]
 */
export function collectScanTargets(projectRoot, scanDirCandidates = DEFAULT_SCAN_DIR_CANDIDATES) {
  const scanRoots = scanDirCandidates.map((d) => path.join(projectRoot, d)).filter(exists);
  if (scanRoots.length === 0) return { scanRoots, targets: [] };

  const files = [];
  for (const r of scanRoots) walk(r, files);
  const targets = files.filter((f) => DEFAULT_SCAN_EXTS.has(path.extname(f)));
  return { scanRoots, targets };
}

/**
 * @param {string} projectRoot
 * @param {string[]} issues
 * @param {string[]} ok
 * @param {string} label
 */
export function printContractReport(projectRoot, issues, ok, label = 'tfds-contract-check') {
  console.log(`\n[${label}] 项目根:`, projectRoot);
  console.log('\n── 已通过 ──');
  if (ok.length === 0) console.log('（无）');
  else ok.forEach((l) => console.log('✓', l));
  console.log('\n── 待处理 / 提示 ──');
  if (issues.length === 0) console.log('（无）— 未发现明显漂移信号。');
  else issues.forEach((l) => console.log('!', l));
  console.log('');
}
