// i18n 国际化单测
// 依据：02-architecture-design.md §17 国际化、F4 错误码 key 命名
// 覆盖：t() 默认 zh-CN / en-US / 缺失 key 回退 / getLocale navigator 检测

import { describe, it, expect, afterEach } from "vitest";
import { t, getLocale, translations } from "./i18n";

describe("t() 翻译", () => {
  it("显式 zh-CN 返回中文翻译", () => {
    expect(t("common.loading", "zh-CN")).toBe("加载中...");
    expect(t("common.error", "zh-CN")).toBe("加载失败");
    expect(t("nav.dashboard", "zh-CN")).toBe("仪表盘");
  });

  it("显式 en-US 返回英文翻译", () => {
    expect(t("common.loading", "en-US")).toBe("Loading...");
    expect(t("nav.dashboard", "en-US")).toBe("Dashboard");
    expect(t("error.iam.invalid_credentials", "en-US")).toBe(
      "Invalid email or password",
    );
  });

  it("zh-CN 与 en-US 同 key 返回不同值", () => {
    expect(t("common.save", "zh-CN")).not.toBe(t("common.save", "en-US"));
    expect(t("common.save", "zh-CN")).toBe("保存");
    expect(t("common.save", "en-US")).toBe("Save");
  });

  it("locale 表未定义的 key 回退到 DEFAULT_LOCALE（zh-CN）再回退到 key 本身", () => {
    // 当前两份 locale 表 key 完全对齐，未对齐场景用任意缺失 key 验证
    // 实现：translations[locale]?.[key] ?? translations[DEFAULT_LOCALE]?.[key] ?? key
    const key = "test.key.only.zh";
    expect(t(key, "en-US")).toBe(key);
  });

  it("两份 locale 均未定义的 key 返回 key 本身", () => {
    const key = "nonexistent.key.totally.fake";
    expect(t(key, "zh-CN")).toBe(key);
    expect(t(key, "en-US")).toBe(key);
  });

  it("覆盖所有通用 / 导航 / 错误码 key", () => {
    const commonKeys = [
      "common.loading",
      "common.error",
      "common.retry",
      "common.save",
      "common.cancel",
      "common.confirm",
    ];
    for (const k of commonKeys) {
      expect(t(k, "zh-CN")).toBeTruthy();
      expect(t(k, "en-US")).toBeTruthy();
    }
    const navKeys = [
      "nav.dashboard",
      "nav.grades",
      "nav.exams",
      "nav.attendance",
      "nav.classes",
      "nav.homework",
      "nav.weakness",
      "nav.learningPath",
      "nav.trend",
      "nav.notifications",
      "nav.preferences",
      "nav.settings",
    ];
    for (const k of navKeys) {
      expect(t(k, "zh-CN")).toBeTruthy();
      expect(t(k, "en-US")).toBeTruthy();
    }
    const errorKeys = [
      "error.iam.invalid_credentials",
      "error.iam.invalid_refresh",
      "error.iam.token_expired",
      "error.parent.child_not_found",
      "error.parent.permission_denied",
      "error.parent.network_error",
      "error.parent.graphql_error",
    ];
    for (const k of errorKeys) {
      expect(t(k, "zh-CN")).toBeTruthy();
      expect(t(k, "en-US")).toBeTruthy();
    }
  });

  it("通知事件 key 在两种 locale 都有翻译", () => {
    const notifKeys = [
      "notification.grade_recorded",
      "notification.homework_graded",
      "notification.homework_assigned",
      "notification.exam_published",
      "notification.attendance_alert",
      "notification.school_announcement",
      "notification.teacher_message",
      "notification.fee_reminder",
      "notification.event_invitation",
    ];
    for (const k of notifKeys) {
      expect(t(k, "zh-CN")).toBeTruthy();
      expect(t(k, "en-US")).toBeTruthy();
    }
  });

  it("子女切换相关 key", () => {
    expect(t("child.switcher.empty", "zh-CN")).toBe("未绑定子女");
    expect(t("child.switcher.empty", "en-US")).toBe("No child bound");
    expect(t("child.switcher.select", "zh-CN")).toBe("选择子女");
    expect(t("child.switcher.select", "en-US")).toBe("Select child");
  });
});

describe("getLocale()", () => {
  const originalNavigator = navigator;

  afterEach(() => {
    // 还原 navigator
    Object.defineProperty(window, "navigator", {
      value: originalNavigator,
      configurable: true,
    });
  });

  it("navigator.language 以 en 开头 → en-US", () => {
    Object.defineProperty(window, "navigator", {
      value: { language: "en-US" },
      configurable: true,
    });
    expect(getLocale()).toBe("en-US");
  });

  it("navigator.language 以 en-GB 开头也 → en-US", () => {
    Object.defineProperty(window, "navigator", {
      value: { language: "en-GB" },
      configurable: true,
    });
    expect(getLocale()).toBe("en-US");
  });

  it("navigator.language 为 zh-CN → 默认 zh-CN", () => {
    Object.defineProperty(window, "navigator", {
      value: { language: "zh-CN" },
      configurable: true,
    });
    expect(getLocale()).toBe("zh-CN");
  });

  it("navigator.language 为非 en 开头 → 默认 zh-CN", () => {
    Object.defineProperty(window, "navigator", {
      value: { language: "ja-JP" },
      configurable: true,
    });
    expect(getLocale()).toBe("zh-CN");
  });
});

describe("translations 导出", () => {
  it("包含 zh-CN 和 en-US 两份", () => {
    expect(translations["zh-CN"]).toBeDefined();
    expect(translations["en-US"]).toBeDefined();
  });

  it("zh-CN 表项数与 en-US 一致（覆盖对齐）", () => {
    const zhKeys = Object.keys(translations["zh-CN"]!);
    const enKeys = Object.keys(translations["en-US"]!);
    expect(zhKeys.length).toBe(enKeys.length);
    for (const k of zhKeys) {
      expect(enKeys).toContain(k);
    }
  });
});
