// @vitest-environment jsdom

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { render } from "@testing-library/react";
import { ThemePreviewPanel } from "./ThemePreviewPanel";

const makePalette = () => [
  {
    name: "background",
    dark: { oklch: "oklch(0.14 0.01 240)", hex: "#1e1e2e", wcagAA: true },
    light: { oklch: "oklch(0.94 0.005 240)", hex: "#eff1f5", wcagAA: true },
  },
  {
    name: "surface",
    dark: { oklch: "oklch(0.18 0.01 240)", hex: "#181825", wcagAA: true },
    light: { oklch: "oklch(0.90 0.006 240)", hex: "#e6e9ef", wcagAA: true },
  },
  {
    name: "text",
    dark: { oklch: "oklch(0.93 0.008 240)", hex: "#cdd6f4", wcagAA: true },
    light: { oklch: "oklch(0.28 0.008 240)", hex: "#4c4f69", wcagAA: true },
  },
];

describe("ThemePreviewPanel", () => {
  let originalSetProperty: typeof CSSStyleDeclaration.prototype.setProperty;
  let documentSetPropertySpy: ReturnType<typeof vi.spyOn>;

  beforeEach(() => {
    originalSetProperty = CSSStyleDeclaration.prototype.setProperty;
    documentSetPropertySpy = vi.spyOn(
      document.documentElement.style,
      "setProperty",
    );
  });

  afterEach(() => {
    CSSStyleDeclaration.prototype.setProperty = originalSetProperty;
    vi.restoreAllMocks();
  });

  it("renders a container with className nexus-theme-preview", () => {
    const { container } = render(
      <ThemePreviewPanel palette={[]} variant="dark" />,
    );
    const preview = container.querySelector(".nexus-theme-preview");
    expect(preview).toBeTruthy();
  });

  it("has aria-label='Theme preview' on the container", () => {
    const { container } = render(
      <ThemePreviewPanel palette={[]} variant="dark" />,
    );
    const preview = container.querySelector(".nexus-theme-preview");
    expect(preview?.getAttribute("aria-label")).toBe("Theme preview");
  });

  it("has an aria-live='polite' region", () => {
    const { container } = render(
      <ThemePreviewPanel palette={[]} variant="dark" />,
    );
    const liveRegion = container.querySelector('[aria-live="polite"]');
    expect(liveRegion).toBeTruthy();
  });

  it("announces 'Palette updated' when palette is provided", () => {
    const palette = makePalette();
    const { container } = render(
      <ThemePreviewPanel palette={palette} variant="dark" />,
    );
    const liveRegion = container.querySelector('[aria-live="polite"]');
    expect(liveRegion?.textContent).toBe("Palette updated");
  });

  it("sets CSS variables on the container element for dark variant", () => {
    const palette = makePalette();
    const { container } = render(
      <ThemePreviewPanel palette={palette} variant="dark" />,
    );
    const preview = container.querySelector(".nexus-theme-preview") as HTMLElement;
    expect(preview).toBeTruthy();
    // dark background role should set --background to dark hex
    expect(preview.style.getPropertyValue("--background")).toBe("#1e1e2e");
  });

  it("sets CSS variables on the container element for light variant", () => {
    const palette = makePalette();
    const { container } = render(
      <ThemePreviewPanel palette={palette} variant="light" />,
    );
    const preview = container.querySelector(".nexus-theme-preview") as HTMLElement;
    expect(preview).toBeTruthy();
    // light background role should set --background to light hex
    expect(preview.style.getPropertyValue("--background")).toBe("#eff1f5");
  });

  it("does NOT call document.documentElement.style.setProperty", () => {
    const palette = makePalette();
    render(<ThemePreviewPanel palette={palette} variant="dark" />);
    expect(documentSetPropertySpy).not.toHaveBeenCalled();
  });
});
