import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { QueueView } from "@/components/QueueView";
import { useFocusStore } from "@/stores/focus-store";
import { makeFocusItem } from "../helpers/fixtures";

describe("QueueView", () => {
  beforeEach(() => {
    useFocusStore.setState({
      current: null,
      queue: [],
      isLoading: false,
      error: null,
    });
  });

  it("shows empty state when no items", () => {
    render(<QueueView onSetFocus={vi.fn()} onSwitchToFocus={vi.fn()} />);
    expect(screen.getByText(/no items/i)).toBeInTheDocument();
  });

  it("groups items by type with section headers", () => {
    useFocusStore.setState({
      current: makeFocusItem({ id: "current" }),
      queue: [
        makeFocusItem({ id: "r1", type: "mr_review", title: "Review A" }),
        makeFocusItem({ id: "r2", type: "mr_review", title: "Review B" }),
        makeFocusItem({ id: "i1", type: "issue", title: "Issue A" }),
        makeFocusItem({
          id: "m1",
          type: "mr_authored",
          title: "My MR",
        }),
      ],
    });

    render(<QueueView onSetFocus={vi.fn()} onSwitchToFocus={vi.fn()} />);

    expect(screen.getByText(/REVIEWS/i)).toBeInTheDocument();
    expect(screen.getByText(/ISSUES/i)).toBeInTheDocument();
    expect(screen.getByText(/AUTHORED MRS/i)).toBeInTheDocument();
  });

  it("shows item count in section headers", () => {
    useFocusStore.setState({
      current: makeFocusItem({ id: "current", type: "issue" }),
      queue: [
        makeFocusItem({ id: "r1", type: "mr_review" }),
        makeFocusItem({ id: "r2", type: "mr_review" }),
        makeFocusItem({ id: "i1", type: "issue" }),
      ],
    });

    render(<QueueView onSetFocus={vi.fn()} onSwitchToFocus={vi.fn()} />);

    // Text is split across elements, so use a function matcher
    const reviewsHeader = screen.getByText((_content, element) => {
      return element?.tagName === "H2" && element.textContent === "REVIEWS (2)";
    });
    expect(reviewsHeader).toBeInTheDocument();

    const issuesHeader = screen.getByText((_content, element) => {
      return element?.tagName === "H2" && element.textContent === "ISSUES (2)";
    });
    expect(issuesHeader).toBeInTheDocument();
  });

  it("includes current focus item in the list", () => {
    useFocusStore.setState({
      current: makeFocusItem({
        id: "focused",
        type: "mr_review",
        title: "Focused item",
      }),
      queue: [
        makeFocusItem({ id: "q1", type: "issue", title: "Queued item" }),
      ],
    });

    render(<QueueView onSetFocus={vi.fn()} onSwitchToFocus={vi.fn()} />);

    expect(screen.getByText("Focused item")).toBeInTheDocument();
    expect(screen.getByText("Queued item")).toBeInTheDocument();
  });

  it("calls onSetFocus when an item is clicked", async () => {
    const onSetFocus = vi.fn();
    const user = userEvent.setup();

    useFocusStore.setState({
      current: makeFocusItem({ id: "current" }),
      queue: [
        makeFocusItem({ id: "target", type: "issue", title: "Click me" }),
      ],
    });

    render(<QueueView onSetFocus={onSetFocus} onSwitchToFocus={vi.fn()} />);

    await user.click(screen.getByText("Click me"));
    expect(onSetFocus).toHaveBeenCalledWith("target");
  });

  it("marks the current focus item visually", () => {
    useFocusStore.setState({
      current: makeFocusItem({ id: "focused", title: "Current focus" }),
      queue: [],
    });

    const { container } = render(
      <QueueView onSetFocus={vi.fn()} onSwitchToFocus={vi.fn()} />
    );

    expect(container.querySelector("[data-focused='true']")).toBeTruthy();
  });
});
