/**
 * Unit tests for i18n: getLang (window.__DT_LANG), normalizeLang, translate, monthName.
 * Ported from webapp/js/i18n.test.js.
 */

import { describe, it, expect, beforeEach, afterEach } from "vitest";
import {
  getLang,
  normalizeLang,
  translate,
  monthName,
} from "./messages";

describe("getLang", () => {
  const orig__DT_LANG = (globalThis as unknown as { window?: { __DT_LANG?: string } }).window?.__DT_LANG;

  afterEach(() => {
    if (typeof globalThis.window !== "undefined") {
      if (orig__DT_LANG !== undefined) {
        (globalThis.window as unknown as { __DT_LANG?: string }).__DT_LANG = orig__DT_LANG;
      } else {
        delete (globalThis.window as unknown as { __DT_LANG?: string }).__DT_LANG;
      }
    }
  });

  it("returns ru when window.__DT_LANG is ru", () => {
    (globalThis.window as unknown as { __DT_LANG?: string }).__DT_LANG = "ru";
    expect(getLang()).toBe("ru");
  });

  it("returns en when window.__DT_LANG is en", () => {
    (globalThis.window as unknown as { __DT_LANG?: string }).__DT_LANG = "en";
    expect(getLang()).toBe("en");
  });

  it("returns en when window.__DT_LANG is missing", () => {
    delete (globalThis.window as unknown as { __DT_LANG?: string }).__DT_LANG;
    expect(getLang()).toBe("en");
  });

  it("returns en when window.__DT_LANG is invalid (unknown code)", () => {
    (globalThis.window as unknown as { __DT_LANG?: string }).__DT_LANG = "uk";
    expect(getLang()).toBe("en");
  });

  it("returns ru when window.__DT_LANG is ru-RU (normalized)", () => {
    (globalThis.window as unknown as { __DT_LANG?: string }).__DT_LANG = "ru-RU";
    expect(getLang()).toBe("ru");
  });

  it("returns en when window.__DT_LANG is empty string", () => {
    (globalThis.window as unknown as { __DT_LANG?: string }).__DT_LANG = "";
    expect(getLang()).toBe("en");
  });

  it("returns en when window.__DT_LANG is null", () => {
    (globalThis.window as unknown as { __DT_LANG?: string }).__DT_LANG = null as unknown as string;
    expect(getLang()).toBe("en");
  });
});

describe("normalizeLang", () => {
  it("returns ru for ru-like codes", () => {
    expect(normalizeLang("ru")).toBe("ru");
    expect(normalizeLang("ru-RU")).toBe("ru");
  });

  it("returns en for en and others", () => {
    expect(normalizeLang("en")).toBe("en");
    expect(normalizeLang("en-US")).toBe("en");
    expect(normalizeLang("uk")).toBe("en");
  });

  it("returns en for empty or invalid", () => {
    expect(normalizeLang("")).toBe("en");
    expect(normalizeLang(null)).toBe("en");
  });
});

describe("translate", () => {
  it("returns translation for existing key", () => {
    expect(translate("en", "app.title")).toBe("Duty Calendar");
    expect(translate("ru", "app.title")).toBe("Календарь дежурств");
  });

  it("falls back to en when key missing in lang", () => {
    expect(translate("ru", "app.title")).toBe("Календарь дежурств");
    expect(translate("en", "loading")).toBe("Loading…");
  });

  it("returns key when key missing in both", () => {
    expect(translate("en", "missing.key")).toBe("missing.key");
    expect(translate("ru", "unknown")).toBe("unknown");
  });

  it("replaces params placeholder", () => {
    expect(translate("en", "duty.until", { time: "14:00" })).toBe("until 14:00");
    expect(translate("ru", "duty.until", { time: "09:30" })).toBe("до 09:30");
  });

  it("handles empty params", () => {
    expect(translate("en", "loading", {})).toBe("Loading…");
  });
});

describe("monthName", () => {
  it("returns month name for 0-based index", () => {
    expect(monthName("en", 0)).toBe("January");
    expect(monthName("en", 11)).toBe("December");
    expect(monthName("ru", 0)).toBe("Январь");
  });

  it("returns empty string for out-of-range", () => {
    expect(monthName("en", 12)).toBe("");
    expect(monthName("en", -1)).toBe("");
  });
});
