import { afterEach, beforeEach, expect, test, vi } from "vitest";
import { screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { renderApp } from "../test/render";
import { ThemeSwitch } from "./theme-switch";

beforeEach(() => {
  vi.stubGlobal("matchMedia", (query: string) => ({
    matches: false,
    media: query,
    onchange: null,
    addEventListener: vi.fn(),
    removeEventListener: vi.fn(),
    addListener: vi.fn(),
    removeListener: vi.fn(),
    dispatchEvent: vi.fn(),
  }));
});

afterEach(() => {
  vi.unstubAllGlobals();
  localStorage.clear();
  document.documentElement.classList.remove("dark");
});

test("selecting Dark applies the dark class and persists", async () => {
  renderApp(<ThemeSwitch />);
  await userEvent.click(screen.getByRole("button", { name: /dark/i }));
  expect(document.documentElement.classList.contains("dark")).toBe(true);
  expect(localStorage.getItem("theme")).toBe("dark");
  expect(screen.getByRole("button", { name: /dark/i })).toHaveAttribute("aria-pressed", "true");
});

test("selecting Light removes the dark class and persists", async () => {
  localStorage.setItem("theme", "dark");
  renderApp(<ThemeSwitch />);
  await userEvent.click(screen.getByRole("button", { name: /light/i }));
  expect(document.documentElement.classList.contains("dark")).toBe(false);
  expect(localStorage.getItem("theme")).toBe("light");
});

test("selecting System resolves via prefers-color-scheme", async () => {
  vi.stubGlobal("matchMedia", (query: string) => ({
    matches: true,
    media: query,
    onchange: null,
    addEventListener: vi.fn(),
    removeEventListener: vi.fn(),
    addListener: vi.fn(),
    removeListener: vi.fn(),
    dispatchEvent: vi.fn(),
  }));
  renderApp(<ThemeSwitch />);
  await userEvent.click(screen.getByRole("button", { name: /system/i }));
  expect(localStorage.getItem("theme")).toBe("system");
  expect(document.documentElement.classList.contains("dark")).toBe(true);
});
