import { beforeEach, describe, expect, it, vi } from "vitest";

const { mockBrowser } = vi.hoisted(() => ({
  mockBrowser: { value: true },
}));

vi.mock("$app/environment", () => ({
  get browser() {
    return mockBrowser.value;
  },
}));

// Mock localStorage and document before importing theme
const mockLocalStorage: Record<string, string> = {};
vi.stubGlobal("localStorage", {
  getItem: vi.fn((key: string) => mockLocalStorage[key] ?? null),
  setItem: vi.fn((key: string, value: string) => {
    mockLocalStorage[key] = value;
  }),
});

vi.stubGlobal("document", {
  documentElement: {
    setAttribute: vi.fn(),
  },
});

describe("theme store", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    Object.keys(mockLocalStorage).forEach((k) => delete mockLocalStorage[k]);
    mockBrowser.value = true;
  });

  it("defaults to dark theme", async () => {
    // Re-import to get a fresh store
    const { theme } = await import("./theme");

    let value: string | undefined;
    const unsub = theme.subscribe((v) => {
      value = v;
    });

    expect(value).toBe("dark");
    unsub();
  });

  it("toggle switches between dark and light", async () => {
    const { theme } = await import("./theme");

    let value: string | undefined;
    const unsub = theme.subscribe((v) => {
      value = v;
    });

    theme.toggle();
    expect(value).toBe("light");

    theme.toggle();
    expect(value).toBe("dark");

    unsub();
  });

  it("set updates the theme directly", async () => {
    const { theme } = await import("./theme");

    let value: string | undefined;
    const unsub = theme.subscribe((v) => {
      value = v;
    });

    theme.set("light");
    expect(value).toBe("light");

    theme.set("dark");
    expect(value).toBe("dark");

    unsub();
  });
});
