import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { render } from "solid-js/web";
import type { JSX } from "solid-js";

import ColorWaveBackground from "./ColorWaveBackground";

function mount(comp: () => JSX.Element): HTMLDivElement {
  const container = document.createElement("div");
  document.body.appendChild(container);
  render(() => comp(), container);
  return container;
}

beforeEach(() => {
  document.body.innerHTML = "";

  Object.defineProperty(window, "matchMedia", {
    writable: true,
    value: vi.fn((query: string) => ({
      matches: query === "(prefers-reduced-motion: reduce)",
      media: query,
      onchange: null,
      addListener: vi.fn(),
      removeListener: vi.fn(),
      addEventListener: vi.fn(),
      removeEventListener: vi.fn(),
      dispatchEvent: vi.fn(),
    })),
    configurable: true,
  });
});

afterEach(() => {
  document.body.innerHTML = "";
});

describe("ColorWaveBackground", () => {
  it("renders a canvas element", () => {
    mount(() => <ColorWaveBackground />);
    const canvas = document.querySelector("canvas");
    expect(canvas).toBeTruthy();
  });

  it("has absolute positioning classes", () => {
    mount(() => <ColorWaveBackground />);
    const canvas = document.querySelector("canvas")!;
    expect(canvas.className).toContain("absolute");
    expect(canvas.className).toContain("inset-0");
    expect(canvas.className).toContain("w-full");
    expect(canvas.className).toContain("h-full");
  });

  it("has pointer-events none style", () => {
    mount(() => <ColorWaveBackground />);
    const canvas = document.querySelector("canvas")!;
    expect(canvas.getAttribute("style")).toContain("pointer-events");
  });

  it("merges custom class prop", () => {
    mount(() => <ColorWaveBackground class="custom-bg" />);
    const canvas = document.querySelector("canvas")!;
    expect(canvas.className).toContain("custom-bg");
  });

  it("accepts yOffset prop", () => {
    mount(() => <ColorWaveBackground yOffset={100} />);
    const canvas = document.querySelector("canvas");
    expect(canvas).toBeTruthy();
  });

  it("accepts scale prop", () => {
    mount(() => <ColorWaveBackground scale={1.5} />);
    const canvas = document.querySelector("canvas");
    expect(canvas).toBeTruthy();
  });

  it("accepts speed prop", () => {
    mount(() => <ColorWaveBackground speed={2} />);
    const canvas = document.querySelector("canvas");
    expect(canvas).toBeTruthy();
  });

  it("respects prefers-reduced-motion", () => {
    Object.defineProperty(window, "matchMedia", {
      writable: true,
      value: vi.fn((query: string) => ({
        matches: true,
        media: query,
        onchange: null,
        addListener: vi.fn(),
        removeListener: vi.fn(),
        addEventListener: vi.fn(),
        removeEventListener: vi.fn(),
        dispatchEvent: vi.fn(),
      })),
      configurable: true,
    });
    mount(() => <ColorWaveBackground />);
    const canvas = document.querySelector("canvas");
    expect(canvas).toBeTruthy();
  });
});
