import { fireEvent, render, screen } from "@solidjs/testing-library";
import { describe, expect, it } from "vitest";
import { Accordion } from "../../../src/components/accordion/index";

describe("Accordion", () => {
  it("all items closed by default", () => {
    render(() => (
      <Accordion>
        <Accordion.Item value="a">
          <Accordion.Header><Accordion.Trigger>A</Accordion.Trigger></Accordion.Header>
          <Accordion.Content data-testid="content-a">Content A</Accordion.Content>
        </Accordion.Item>
      </Accordion>
    ));
    expect(screen.getByTestId("content-a")).toHaveAttribute("hidden");
  });

  it("clicking trigger opens item", () => {
    render(() => (
      <Accordion>
        <Accordion.Item value="a">
          <Accordion.Header><Accordion.Trigger>A</Accordion.Trigger></Accordion.Header>
          <Accordion.Content data-testid="content-a">Content A</Accordion.Content>
        </Accordion.Item>
      </Accordion>
    ));
    fireEvent.click(screen.getByRole("button"));
    expect(screen.getByTestId("content-a")).not.toHaveAttribute("hidden");
  });

  it("single mode: opening one closes another", () => {
    render(() => (
      <Accordion type="single" defaultValue="a">
        <Accordion.Item value="a">
          <Accordion.Header><Accordion.Trigger>A</Accordion.Trigger></Accordion.Header>
          <Accordion.Content data-testid="content-a">Content A</Accordion.Content>
        </Accordion.Item>
        <Accordion.Item value="b">
          <Accordion.Header><Accordion.Trigger>B</Accordion.Trigger></Accordion.Header>
          <Accordion.Content data-testid="content-b">Content B</Accordion.Content>
        </Accordion.Item>
      </Accordion>
    ));
    expect(screen.getByTestId("content-a")).not.toHaveAttribute("hidden");
    fireEvent.click(screen.getAllByRole("button")[1]);
    expect(screen.getByTestId("content-a")).toHaveAttribute("hidden");
    expect(screen.getByTestId("content-b")).not.toHaveAttribute("hidden");
  });

  it("single mode with collapsible=true: clicking open item closes it", () => {
    render(() => (
      <Accordion type="single" collapsible defaultValue="a">
        <Accordion.Item value="a">
          <Accordion.Header><Accordion.Trigger>A</Accordion.Trigger></Accordion.Header>
          <Accordion.Content data-testid="content-a">Content A</Accordion.Content>
        </Accordion.Item>
      </Accordion>
    ));
    fireEvent.click(screen.getByRole("button"));
    expect(screen.getByTestId("content-a")).toHaveAttribute("hidden");
  });

  it("multiple mode: multiple items can be open", () => {
    render(() => (
      <Accordion type="multiple">
        <Accordion.Item value="a">
          <Accordion.Header><Accordion.Trigger>A</Accordion.Trigger></Accordion.Header>
          <Accordion.Content data-testid="content-a">Content A</Accordion.Content>
        </Accordion.Item>
        <Accordion.Item value="b">
          <Accordion.Header><Accordion.Trigger>B</Accordion.Trigger></Accordion.Header>
          <Accordion.Content data-testid="content-b">Content B</Accordion.Content>
        </Accordion.Item>
      </Accordion>
    ));
    fireEvent.click(screen.getAllByRole("button")[0]);
    fireEvent.click(screen.getAllByRole("button")[1]);
    expect(screen.getByTestId("content-a")).not.toHaveAttribute("hidden");
    expect(screen.getByTestId("content-b")).not.toHaveAttribute("hidden");
  });

  it("trigger has aria-expanded", () => {
    render(() => (
      <Accordion>
        <Accordion.Item value="a">
          <Accordion.Header><Accordion.Trigger>A</Accordion.Trigger></Accordion.Header>
          <Accordion.Content>Content A</Accordion.Content>
        </Accordion.Item>
      </Accordion>
    ));
    expect(screen.getByRole("button").getAttribute("aria-expanded")).toBe("false");
    fireEvent.click(screen.getByRole("button"));
    expect(screen.getByRole("button").getAttribute("aria-expanded")).toBe("true");
  });

  it("ArrowDown moves focus to next trigger", () => {
    render(() => (
      <Accordion>
        <Accordion.Item value="a">
          <Accordion.Header><Accordion.Trigger>A</Accordion.Trigger></Accordion.Header>
          <Accordion.Content>Content A</Accordion.Content>
        </Accordion.Item>
        <Accordion.Item value="b">
          <Accordion.Header><Accordion.Trigger>B</Accordion.Trigger></Accordion.Header>
          <Accordion.Content>Content B</Accordion.Content>
        </Accordion.Item>
      </Accordion>
    ));
    const [first] = screen.getAllByRole("button");
    first.focus();
    fireEvent.keyDown(first, { key: "ArrowDown" });
    expect(document.activeElement).toBe(screen.getAllByRole("button")[1]);
  });
});
