// PR11.5 i18n 校验：扫 src/ 里所有 t("...") 调用，比对 locales/*.json 全部 key 在所有 locale 都有。
// 任一缺失 → 非零退出，CI 卡死。

import * as fs from "node:fs";
import * as path from "node:path";

// 编译产物落 scripts/_compiled/，所以 __dirname 在那里；回退两级到 desktop/
const ROOT = path.resolve(__dirname, "..", "..");
const SRC_DIR = path.join(ROOT, "src");
const LOCALES_DIR = path.join(ROOT, "locales");

function walkTs(dir: string): string[] {
  const out: string[] = [];
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    const p = path.join(dir, entry.name);
    if (entry.isDirectory()) out.push(...walkTs(p));
    else if (entry.isFile() && p.endsWith(".ts")) out.push(p);
  }
  return out;
}

function extractKeys(file: string): string[] {
  const src = fs.readFileSync(file, "utf8");
  const keys: string[] = [];
  const re = /\bt\(\s*["']([^"']+)["']\s*\)/g;
  let m: RegExpExecArray | null;
  while ((m = re.exec(src)) !== null) keys.push(m[1]);
  return keys;
}

function main(): void {
  const tsFiles = walkTs(SRC_DIR);
  const usedKeys = new Set<string>();
  for (const f of tsFiles) for (const k of extractKeys(f)) usedKeys.add(k);

  const localeFiles = fs.readdirSync(LOCALES_DIR).filter((f) => f.endsWith(".json"));
  const localeMaps: Record<string, Record<string, string>> = {};
  for (const lf of localeFiles) {
    localeMaps[lf] = JSON.parse(fs.readFileSync(path.join(LOCALES_DIR, lf), "utf8"));
  }

  let missing = 0;
  for (const key of usedKeys) {
    for (const [lf, map] of Object.entries(localeMaps)) {
      if (!(key in map)) {
        console.error(`[i18n] missing key in ${lf}: ${key}`);
        missing++;
      }
    }
  }

  // 反向：locale 里有但代码没用的（warning，不阻断）
  for (const [lf, map] of Object.entries(localeMaps)) {
    for (const key of Object.keys(map)) {
      if (!usedKeys.has(key)) {
        console.warn(`[i18n] unused key in ${lf}: ${key}`);
      }
    }
  }

  if (missing > 0) {
    console.error(`\n[i18n] FAILED: ${missing} missing keys across locales`);
    process.exit(1);
  }
  console.log(`[i18n] OK: ${usedKeys.size} keys × ${Object.keys(localeMaps).length} locales`);
}

main();
