import * as React from "react";
import axe from "axe-core";
import { fireEvent, render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import {
  AppShell,
  Button,
  FormField,
  Input,
  ThemeProvider,
  useTheme,
} from "../src";

function ThemeControl() {
  const { resolvedTheme, toggleTheme } = useTheme();
  return <Button onClick={toggleTheme}>Current: {resolvedTheme}</Button>;
}

describe("core UI contracts", () => {
  it("persists and applies theme changes", () => {
    render(<ThemeProvider defaultTheme="dark"><ThemeControl /></ThemeProvider>);
    fireEvent.click(screen.getByRole("button", { name: "Current: dark" }));
    expect(document.documentElement).toHaveClass("light");
    expect(window.localStorage.getItem("jason-ui-theme")).toBe("light");
  });

  it("associates form help and errors with the control", () => {
    render(
      <FormField label="Workspace name" description="Used in navigation" error="Name is required">
        <Input />
      </FormField>
    );
    const input = screen.getByLabelText("Workspace name");
    expect(input).toHaveAttribute("aria-invalid", "true");
    expect(input.getAttribute("aria-describedby")).toContain("-error");
  });

  it("provides mobile navigation and current-page semantics", () => {
    const onClick = vi.fn();
    render(
      <AppShell
        brand="Acme"
        nav={[{ label: "Dashboard", active: true, onClick }]}
      >
        Content
      </AppShell>
    );
    fireEvent.click(screen.getByRole("button", { name: "Open navigation" }));
    const current = screen.getAllByRole("button", { name: "Dashboard" }).at(-1)!;
    expect(current).toHaveAttribute("aria-current", "page");
    fireEvent.click(current);
    expect(onClick).toHaveBeenCalledOnce();
  });

  it("has no serious accessibility violations in representative primitives", async () => {
    const { container } = render(
      <main>
        <FormField label="Email" description="We never share it."><Input type="email" /></FormField>
        <Button>Save</Button>
      </main>
    );
    const results = await axe.run(container, { runOnly: { type: "tag", values: ["wcag2a", "wcag2aa"] } });
    expect(results.violations.filter((violation) => violation.impact === "serious" || violation.impact === "critical")).toEqual([]);
  });
});
