import { describe, expect, test } from "bun:test";

import {
  applyThemeMode,
  parseThemePreference,
  readThemePreference,
  resolveEffectiveTheme,
  THEME_PREFERENCE_STORAGE_KEY,
  writeThemePreference,
} from "../../../src/web/hooks/use-theme-preference";

function createMemoryStorage(initialValue?: string): Storage {
  const data = new Map<string, string>();
  if (initialValue !== undefined) data.set(THEME_PREFERENCE_STORAGE_KEY, initialValue);

  return {
    clear: () => data.clear(),
    getItem: (key: string) => data.get(key) ?? null,
    key: (index: number) => Array.from(data.keys())[index] ?? null,
    get length() {
      return data.size;
    },
    removeItem: (key: string) => void data.delete(key),
    setItem: (key: string, value: string) => void data.set(key, value),
  };
}

function createThrowingStorage(): Storage {
  return {
    clear: () => {
      throw new Error("storage unavailable");
    },
    getItem: () => {
      throw new Error("storage unavailable");
    },
    key: () => {
      throw new Error("storage unavailable");
    },
    get length(): number {
      throw new Error("storage unavailable");
    },
    removeItem: () => {
      throw new Error("storage unavailable");
    },
    setItem: () => {
      throw new Error("storage unavailable");
    },
  };
}

describe("use-theme-preference 工具函数", () => {
  test("解析有效主题偏好并对非法值回退为系统", () => {
    expect(parseThemePreference("system")).toBe("system");
    expect(parseThemePreference("light")).toBe("light");
    expect(parseThemePreference("dark")).toBe("dark");
    expect(parseThemePreference("unknown")).toBe("system");
    expect(parseThemePreference(null)).toBe("system");
  });

  test("根据系统模式计算有效主题", () => {
    expect(resolveEffectiveTheme("system", true)).toBe("dark");
    expect(resolveEffectiveTheme("system", false)).toBe("light");
    expect(resolveEffectiveTheme("light", true)).toBe("light");
    expect(resolveEffectiveTheme("dark", false)).toBe("dark");
  });

  test("读取本地存储偏好并在非法值时回退", () => {
    expect(readThemePreference(createMemoryStorage("dark"))).toBe("dark");
    expect(readThemePreference(createMemoryStorage("bad-value"))).toBe("system");
  });

  test("本地存储不可用时读取和写入均不抛错", () => {
    const storage = createThrowingStorage();
    expect(readThemePreference(storage)).toBe("system");
    expect(() => writeThemePreference("dark", storage)).not.toThrow();
  });

  test("应用有效主题到指定根元素", () => {
    const root = document.createElement("html");
    applyThemeMode("dark", root);
    expect(root.getAttribute("theme-mode")).toBe("dark");
  });
});
