import { createRef } from "react";
import { render, screen } from "@testing-library/react";
import { Breadcrumbs, BreadcrumbItem } from ".";
import { Link } from "../Link";

const CLASS_NAME = "mobius-breadcrumb";
const ITEM_CLASS_NAME = "mobius-breadcrumb__item";

describe("Breadcrumbs", () => {
  it("renders without errors", () => {
    const { container } = render(
      <Breadcrumbs>
        <BreadcrumbItem key="business-insurance">
          <Link href="/business-insurance">Business insurance</Link>
        </BreadcrumbItem>
        <BreadcrumbItem key="tradesmen">
          <Link href="/tradesmen">Tradesmen</Link>
        </BreadcrumbItem>
        <BreadcrumbItem key="beauty-salon-insurance">
          Beauty salon insurance
        </BreadcrumbItem>
      </Breadcrumbs>,
    );
    expect(container).toBeInTheDocument();
  });

  describe("uses correct class names", () => {
    it("uses Mobius class for top level Breadcrumb", () => {
      render(
        <Breadcrumbs data-testid="test">
          <BreadcrumbItem key="business-insurance">
            <Link href="/business-insurance">Business insurance</Link>
          </BreadcrumbItem>
          <BreadcrumbItem key="tradesmen">
            <Link href="/tradesmen">Tradesmen</Link>
          </BreadcrumbItem>
        </Breadcrumbs>,
      );
      expect(screen.getByTestId("test")).toHaveClass("mobius");
    });

    it("uses base Mobius class for top level Breadcrumb", () => {
      render(
        <Breadcrumbs data-testid="test">
          <BreadcrumbItem key="business-insurance">
            <Link href="/business-insurance">Business insurance</Link>
          </BreadcrumbItem>
          <BreadcrumbItem key="tradesmen">
            <Link href="/tradesmen">Tradesmen</Link>
          </BreadcrumbItem>
        </Breadcrumbs>,
      );
      expect(screen.getByTestId("test")).toHaveClass(CLASS_NAME);
    });

    it("includes custom class name for top level Breadcrumb", () => {
      render(
        <Breadcrumbs data-testid="test" className="my-class">
          <BreadcrumbItem key="business-insurance">
            <Link href="/business-insurance">Business insurance</Link>
          </BreadcrumbItem>
          <BreadcrumbItem key="tradesmen">
            <Link href="/tradesmen">Tradesmen</Link>
          </BreadcrumbItem>
        </Breadcrumbs>,
      );
      expect(screen.getByTestId("test")).toHaveClass("my-class");
      expect(screen.getByTestId("test")).toHaveClass(CLASS_NAME);
    });

    it("includes custom class names for child Breadcrumb <li> items", () => {
      render(
        <Breadcrumbs>
          <BreadcrumbItem key="business-insurance" data-testid="business">
            <Link href="/business-insurance">Business insurance</Link>
          </BreadcrumbItem>
          <BreadcrumbItem
            key="tradesmen"
            className="trades-breadcrumb"
            data-testid="trades"
          >
            <Link href="/tradesmen">Tradesmen</Link>
          </BreadcrumbItem>
        </Breadcrumbs>,
      );
      expect(screen.getByTestId("business").closest("li")).toHaveClass(
        ITEM_CLASS_NAME,
      );
      expect(screen.getByTestId("trades").closest("li")).toHaveClass(
        "trades-breadcrumb",
      );
      expect(screen.getByTestId("trades").closest("li")).toHaveClass(
        ITEM_CLASS_NAME,
      );
    });
  });

  describe("semantic HTML and ARIA", () => {
    it("renders a <nav> element with aria-label", () => {
      render(
        <Breadcrumbs data-testid="nav">
          <BreadcrumbItem>Home</BreadcrumbItem>
          <BreadcrumbItem>Current</BreadcrumbItem>
        </Breadcrumbs>,
      );
      const nav = screen.getByTestId("nav");
      expect(nav.nodeName).toBe("NAV");
      expect(nav).toHaveAttribute("aria-label", "Breadcrumbs");
    });

    it("supports custom aria-label on the nav element", () => {
      render(
        <Breadcrumbs data-testid="nav" aria-label="Page navigation">
          <BreadcrumbItem>Home</BreadcrumbItem>
          <BreadcrumbItem>Current</BreadcrumbItem>
        </Breadcrumbs>,
      );
      expect(screen.getByTestId("nav")).toHaveAttribute(
        "aria-label",
        "Page navigation",
      );
    });

    it("contains a <ul> list inside the nav", () => {
      render(
        <Breadcrumbs data-testid="nav">
          <BreadcrumbItem>Home</BreadcrumbItem>
          <BreadcrumbItem>Current</BreadcrumbItem>
        </Breadcrumbs>,
      );
      expect(screen.getByRole("list")).toBeInTheDocument();
    });

    it("renders each BreadcrumbItem as a <li>", () => {
      render(
        <Breadcrumbs>
          <BreadcrumbItem>Home</BreadcrumbItem>
          <BreadcrumbItem>About</BreadcrumbItem>
          <BreadcrumbItem>Current</BreadcrumbItem>
        </Breadcrumbs>,
      );
      expect(screen.getAllByRole("listitem")).toHaveLength(3);
    });

    it("sets aria-current on the last (current) item", () => {
      render(
        <Breadcrumbs>
          <BreadcrumbItem>
            <Link href="/home">Home</Link>
          </BreadcrumbItem>
          <BreadcrumbItem>Current page</BreadcrumbItem>
        </Breadcrumbs>,
      );
      // The last item gets isCurrent=true automatically, which sets aria-current="page"
      const currentItem = screen.getByText("Current page");
      expect(currentItem).toHaveAttribute("aria-current", "page");
    });

    it("does not set aria-current on non-current items", () => {
      render(
        <Breadcrumbs>
          <BreadcrumbItem>
            <Link href="/home" data-testid="home-link">
              Home
            </Link>
          </BreadcrumbItem>
          <BreadcrumbItem>Current page</BreadcrumbItem>
        </Breadcrumbs>,
      );
      expect(screen.getByTestId("home-link")).not.toHaveAttribute(
        "aria-current",
      );
    });

    it("sets aria-disabled on a disabled item", () => {
      render(
        <Breadcrumbs>
          <BreadcrumbItem isDisabled>Disabled item</BreadcrumbItem>
          <BreadcrumbItem>Current</BreadcrumbItem>
        </Breadcrumbs>,
      );
      expect(screen.getByText("Disabled item")).toHaveAttribute(
        "aria-disabled",
        "true",
      );
    });

    it("sets aria-disabled on the current (last) item", () => {
      render(
        <Breadcrumbs>
          <BreadcrumbItem>
            <Link href="/home">Home</Link>
          </BreadcrumbItem>
          <BreadcrumbItem>Current page</BreadcrumbItem>
        </Breadcrumbs>,
      );
      // isCurrent=true causes aria-disabled to be true (current page is not navigable)
      expect(screen.getByText("Current page")).toHaveAttribute(
        "aria-disabled",
        "true",
      );
    });

    it("hides the separator from assistive technology", () => {
      render(
        <Breadcrumbs>
          <BreadcrumbItem>
            <Link href="/home">Home</Link>
          </BreadcrumbItem>
          <BreadcrumbItem>Current</BreadcrumbItem>
        </Breadcrumbs>,
      );
      expect(screen.getByText(">")).toHaveAttribute("aria-hidden", "true");
    });
  });

  it("forwards ref", () => {
    const ref = createRef<HTMLUListElement>();
    render(
      <Breadcrumbs ref={ref}>
        <BreadcrumbItem>Home</BreadcrumbItem>
      </Breadcrumbs>,
    );
    expect(ref.current).toBeInstanceOf(HTMLElement);
  });
});
