import { describe, expect, it } from "vitest";
import { getLanguageTag, setLocale, t } from "../src/lib/i18n";
import { formatMinor } from "../src/lib/money";
import sv from "../src/locales/sv/common.json";
import en from "../src/locales/en/common.json";
import es from "../src/locales/es/common.json";
import it_ from "../src/locales/it/common.json";
import de from "../src/locales/de/common.json";
import fr from "../src/locales/fr/common.json";
import da from "../src/locales/da/common.json";
import nb from "../src/locales/nb/common.json";
import fi from "../src/locales/fi/common.json";
import nl from "../src/locales/nl/common.json";
import pl from "../src/locales/pl/common.json";
import pt from "../src/locales/pt/common.json";

describe("i18n (i18n-spec §5, §7–8 – M4, D-031)", () => {
  it("ALLA 12 språk har samma basnycklar (pluralvarianter får skilja per språk)", () => {
    const baseKeys = (obj: Record<string, string>) =>
      [
        ...new Set(
          Object.keys(obj).map((k) => {
            const suffix = k.split("_").pop();
            return suffix && ["one", "few", "many", "other"].includes(suffix)
              ? k.slice(0, k.lastIndexOf("_"))
              : k;
          }),
        ),
      ].sort();
    const base = baseKeys(sv);
    const locales = { en, es, it: it_, de, fr, da, nb, fi, nl, pl, pt };
    for (const [name, locale] of Object.entries(locales)) {
      expect(baseKeys(locale), `språk: ${name}`).toEqual(base);
    }
  });

  it("interpolerar {brand} från konfig – aldrig hårdkodat namn", () => {
    setLocale("sv-SE");
    const text = t("memory.title");
    expect(text).not.toContain("{brand}");
    expect(text.length).toBeGreaterThan(0);
  });

  it("plural via Intl.PluralRules: 1 dag / 3 dagar", () => {
    setLocale("sv-SE");
    expect(t("home.expiresIn", { days: 1, count: 1 })).toBe("1 dag kvar");
    expect(t("home.expiresIn", { days: 3, count: 3 })).toBe("3 dagar kvar");
  });

  it("språkbyte utan omstart + fallback till sv för okända språk", () => {
    setLocale("en-US");
    expect(t("tabs.home")).toBe("At home");
    expect(getLanguageTag()).toBe("en-US");
    setLocale("zz-ZZ"); // stöds inte -> sv
    expect(t("tabs.home")).toBe("Hemma");
    setLocale("sv-SE");
  });

  it("pengar formatteras per språk ur minor units (i18n-spec §20)", () => {
    setLocale("sv-SE");
    const svText = formatMinor(7900, "SEK");
    expect(svText).toMatch(/79/);
    setLocale("en-US");
    const enText = formatMinor(7900, "SEK");
    expect(enText).toMatch(/79/);
    expect(enText).not.toBe(svText); // olika locale -> olika formatering
    setLocale("sv-SE");
  });
});

describe("språkpolicy D-031 – automatik + manuellt val", () => {
  it("spanska väljs och pluralformer fungerar", () => {
    setLocale("es-ES");
    expect(t("tabs.whatToEat")).toBe("¿Qué comemos?");
    expect(t("home.expiresIn", { days: 1, count: 1 })).toBe("Queda 1 día");
    expect(t("home.expiresIn", { days: 3, count: 3 })).toBe("Quedan 3 días");
    setLocale("sv-SE");
  });

  it("regional variant faller till primärspråket (es-MX -> es)", () => {
    setLocale("es-MX");
    expect(t("tabs.home")).toBe("En casa");
    expect(getLanguageTag()).toBe("es-MX"); // Intl behåller regionen
    setLocale("sv-SE");
  });

  it("italienska, tyska och franska svarar på sina språk", () => {
    setLocale("it-IT");
    expect(t("tabs.whatToEat")).toBe("Cosa mangiamo?");
    setLocale("de-DE");
    expect(t("tabs.whatToEat")).toBe("Was essen wir?");
    setLocale("fr-FR");
    expect(t("tabs.whatToEat")).toBe("On mange quoi ?");
    setLocale("sv-SE");
  });

  it("polska pluralformer: one/few/many via Intl.PluralRules", () => {
    setLocale("pl-PL");
    expect(t("recipe.portions", { count: 1 })).toBe("1 porcja");
    expect(t("recipe.portions", { count: 3 })).toBe("3 porcje");
    expect(t("recipe.portions", { count: 5 })).toBe("5 porcji");
    expect(t("recipe.portions", { count: 22 })).toBe("22 porcje");
    setLocale("sv-SE");
  });

  it("nordiska språk + nederländska/portugisiska svarar rätt", () => {
    setLocale("da-DK");
    expect(t("tabs.whatToEat")).toBe("Hvad skal vi spise?");
    setLocale("nb-NO");
    expect(t("tabs.whatToEat")).toBe("Hva skal vi spise?");
    setLocale("fi-FI");
    expect(t("tabs.whatToEat")).toBe("Mitä syödään?");
    setLocale("nl-NL");
    expect(t("tabs.whatToEat")).toBe("Wat eten we?");
    setLocale("pt-PT");
    expect(t("tabs.whatToEat")).toBe("O que vamos comer?");
    setLocale("sv-SE");
  });

  it("ostött språk faller till svenska i t(), utan krasch", () => {
    setLocale("el-GR"); // grekiska stöds inte ännu
    expect(t("tabs.home")).toBe("Hemma");
    setLocale("sv-SE");
  });

  it("pt-BR får portugisiska resurser med brasiliansk Intl-formattering", () => {
    setLocale("pt-BR");
    expect(t("tabs.home")).toBe("Em casa");
    expect(getLanguageTag()).toBe("pt-BR");
    setLocale("sv-SE");
  });
});
