import { act, assertEquals, cleanup, fireEvent, render } from "./setup.ts";
import ThemeToggle from "../../islands/ThemeToggle.tsx";

function resetState() {
  document.documentElement.classList.remove("dark");
  localStorage.removeItem("theme");
}

Deno.test({
  name: "ThemeToggle - renders moon icon in light mode by default",
  fn() {
    resetState();
    const { container } = render(<ThemeToggle />);
    const icon = container.querySelector("i")!;
    assertEquals(icon.classList.contains("bi-moon-stars"), true);
    assertEquals(icon.classList.contains("bi-sun"), false);
    cleanup();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "ThemeToggle - renders sun icon when dark class is present",
  fn() {
    resetState();
    document.documentElement.classList.add("dark");
    let container: HTMLElement;
    act(() => {
      ({ container } = render(<ThemeToggle />));
    });
    const icon = container!.querySelector("i")!;
    assertEquals(icon.classList.contains("bi-sun"), true);
    assertEquals(icon.classList.contains("bi-moon-stars"), false);
    cleanup();
    resetState();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "ThemeToggle - click adds dark class to documentElement",
  fn() {
    resetState();
    const { container } = render(<ThemeToggle />);
    const icon = container.querySelector("i")!;
    act(() => {
      fireEvent.click(icon);
    });
    assertEquals(document.documentElement.classList.contains("dark"), true);
    cleanup();
    resetState();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "ThemeToggle - click toggles icon from moon to sun",
  fn() {
    resetState();
    const { container } = render(<ThemeToggle />);
    const icon = container.querySelector("i")!;
    assertEquals(icon.classList.contains("bi-moon-stars"), true);
    act(() => {
      fireEvent.click(icon);
    });
    const updatedIcon = container.querySelector("i")!;
    assertEquals(updatedIcon.classList.contains("bi-sun"), true);
    assertEquals(updatedIcon.classList.contains("bi-moon-stars"), false);
    cleanup();
    resetState();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "ThemeToggle - second click removes dark class",
  fn() {
    resetState();
    const { container } = render(<ThemeToggle />);
    const icon = container.querySelector("i")!;
    act(() => {
      fireEvent.click(icon);
    });
    assertEquals(document.documentElement.classList.contains("dark"), true);
    act(() => {
      fireEvent.click(container.querySelector("i")!);
    });
    assertEquals(document.documentElement.classList.contains("dark"), false);
    cleanup();
    resetState();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "ThemeToggle - click persists 'dark' to localStorage",
  fn() {
    resetState();
    const { container } = render(<ThemeToggle />);
    act(() => {
      fireEvent.click(container.querySelector("i")!);
    });
    assertEquals(localStorage.getItem("theme"), "dark");
    cleanup();
    resetState();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "ThemeToggle - second click persists 'light' to localStorage",
  fn() {
    resetState();
    const { container } = render(<ThemeToggle />);
    act(() => {
      fireEvent.click(container.querySelector("i")!);
    });
    act(() => {
      fireEvent.click(container.querySelector("i")!);
    });
    assertEquals(localStorage.getItem("theme"), "light");
    cleanup();
    resetState();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "ThemeToggle - click dispatches ThemeChange event",
  fn() {
    resetState();
    let eventDetail: boolean | null = null;
    const listener = (e: Event) => {
      eventDetail = (e as CustomEvent).detail;
    };
    document.addEventListener("ThemeChange", listener);

    const { container } = render(<ThemeToggle />);
    act(() => {
      fireEvent.click(container.querySelector("i")!);
    });
    assertEquals(eventDetail, true);

    document.removeEventListener("ThemeChange", listener);
    cleanup();
    resetState();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "ThemeToggle - has hover classes for both themes",
  fn() {
    resetState();
    const { container } = render(<ThemeToggle />);
    const icon = container.querySelector("i")!;
    assertEquals(icon.className.includes("hover:text-blue-600"), true);
    assertEquals(icon.className.includes("dark:hover:text-blue-400"), true);
    cleanup();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "ThemeToggle - has correct title attribute in light mode",
  fn() {
    resetState();
    const { container } = render(<ThemeToggle />);
    const icon = container.querySelector("i")!;
    assertEquals(icon.getAttribute("title"), "Switch to dark mode");
    cleanup();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "ThemeToggle - has correct title attribute in dark mode",
  fn() {
    resetState();
    document.documentElement.classList.add("dark");
    let container: HTMLElement;
    act(() => {
      ({ container } = render(<ThemeToggle />));
    });
    const icon = container!.querySelector("i")!;
    assertEquals(icon.getAttribute("title"), "Switch to light mode");
    cleanup();
    resetState();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});
