import { existsSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";
import { extname, join, resolve } from "node:path";
import {
  auditLocaleKeys,
  extractTranslationKeysFromFiles,
  flattenMessageKeys,
  loadLocales,
} from "@wrnexus/i18n";

function sourceFiles(root: string): string[] {
  const output: string[] = [];
  const visit = (directory: string) => {
    if (!existsSync(directory)) return;
    for (const entry of readdirSync(directory, { withFileTypes: true })) {
      if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist")
        continue;
      const path = join(directory, entry.name);
      if (entry.isDirectory()) visit(path);
      else if ([".wrn", ".ts", ".tsx", ".js", ".jsx"].includes(extname(entry.name)))
        output.push(path);
    }
  };
  visit(join(root, "app"));
  return output.sort();
}
export function runI18nCommand(appRoot: string, command: string): boolean {
  const root = resolve(appRoot);
  const extracted = extractTranslationKeysFromFiles(sourceFiles(root));
  const keys = [...new Set(extracted.map((entry) => entry.key))].sort();
  const messages = loadLocales(join(root, "app", "locales"), { strict: true });
  const locales = Object.keys(messages).sort();
  const reference = locales[0] ?? "en";
  const audit = auditLocaleKeys(messages, reference);
  const referenceKeys = new Set(flattenMessageKeys(messages[reference] ?? {}));
  const unused = [...referenceKeys].filter((key) => !keys.includes(key)).sort();
  const missingFromReference = keys.filter((key) => !referenceKeys.has(key));
  const report = { reference, locales, extracted: keys, missingFromReference, unused, audit };
  if (command === "extract") {
    const directory = join(root, ".wrnexus");
    mkdirSync(directory, { recursive: true });
    const file = join(directory, "i18n-keys.json");
    writeFileSync(file, `${JSON.stringify(report, null, 2)}\n`, "utf8");
    console.log(`✓ Extracted ${keys.length} translation keys to ${file}`);
    return true;
  }
  if (command !== "validate")
    throw new Error("WRN-I18N-COMMAND: use i18n extract or i18n validate.");
  for (const locale of locales) {
    const missing = [
      ...new Set([...(audit[locale]?.missing ?? []), ...missingFromReference]),
    ].sort();
    if (missing.length) {
      console.log(`Missing in ${locale}:`);
      missing.forEach((key) => console.log(`- ${key}`));
    }
  }
  if (unused.length) {
    console.log("Unused keys:");
    unused.forEach((key) => console.log(`- ${key}`));
  }
  const healthy =
    missingFromReference.length === 0 &&
    Object.values(audit).every((value) => value.missing.length === 0);
  if (healthy) console.log(`✓ ${locales.length} locales contain every extracted key.`);
  return healthy;
}
