import { describe, expect, test } from "bun:test";
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import {
  loadLocales,
  localeDirection,
  makeT,
  renderI18nData,
  resolveI18n,
  resolveLang,
} from "../src/index.ts";

describe("i18n package kit", () => {
  test("loads top-level and namespaced locale files recursively", () => {
    const directory = mkdtempSync(join(tmpdir(), "wrn-i18n-"));
    try {
      writeFileSync(join(directory, "en.json"), JSON.stringify({ app: { title: "Portal" } }));
      mkdirSync(join(directory, "fr"));
      writeFileSync(
        join(directory, "fr", "common.json"),
        JSON.stringify({ hello: "Bonjour {name}" }),
      );
      const i18n = resolveI18n(loadLocales(directory, { strict: true }), {
        default: "en",
        locales: ["en", "fr"],
      });
      expect(makeT(i18n, "fr")("common.hello", { name: "Ajay" })).toBe("Bonjour Ajay");
      expect(resolveLang(i18n, undefined, "en;q=0.6, fr;q=0.9")).toBe("fr");
      expect(resolveLang(i18n, undefined, "*")).toBe("en");
      expect(renderI18nData(i18n, "fr")).toContain("Bonjour");
      expect(renderI18nData(i18n, "fr")).toContain('"directions"');
    } finally {
      rmSync(directory, { recursive: true, force: true });
    }
  });

  test("ships a cookie-backed language switcher that targets the native select", () => {
    const source = readFileSync(
      join(import.meta.dir, "../components/LanguageSwitcher.wrn"),
      "utf8",
    );
    expect(source).toContain("<select");
    expect(source).toContain("data-wire-lang");
    expect(source).toMatch(/<select[\s\S]*data-wire-lang/);
    expect(source).toContain("selected='{locale.value == current}'");
    expect(source).toContain('variant == "segmented"');
    expect(source).toContain("wire-language-switcher--compact");
  });

  test("replaces primitive namespace collisions safely", () => {
    const directory = mkdtempSync(join(tmpdir(), "wrn-i18n-collision-"));
    try {
      writeFileSync(join(directory, "en.json"), JSON.stringify({ common: "legacy" }));
      mkdirSync(join(directory, "en"));
      writeFileSync(join(directory, "en", "common.json"), JSON.stringify({ save: "Save" }));
      const i18n = resolveI18n(loadLocales(directory, { strict: true }), { default: "en" });
      expect(makeT(i18n, "en")("common.save")).toBe("Save");
    } finally {
      rmSync(directory, { recursive: true, force: true });
    }
  });

  test("resolves RTL direction from language subtags", () => {
    expect(localeDirection("ar-IN")).toBe("rtl");
    expect(localeDirection("en-IN")).toBe("ltr");
  });

  test("rejects prototype-polluting locale keys", () => {
    const directory = mkdtempSync(join(tmpdir(), "wrn-i18n-unsafe-"));
    try {
      writeFileSync(join(directory, "en.json"), '{"constructor":{"prototype":{"polluted":true}}}');
      expect(() => loadLocales(directory, { strict: true })).toThrow();
    } finally {
      rmSync(directory, { recursive: true, force: true });
    }
  });
});
