import { render } from "@testing-library/react";

import { Breadcrumbs } from "../Breadcrumbs";

const itemsArr = [
  { url: "/test1", text: "test1-text" },
  { text: "test2-test" },
  { url: "/test3", text: "test3-text" },
];

const complexItemsArr = [
  { url: "/home", text: "Domov" },
  { url: "/products", text: "Produkty" },
  { url: "/electronics", text: "Elektronika" },
  { text: "Mobilné telefóny" },
];

// items array is required
describe("rendering Breadcrumbs", () => {
  describe("initial state", () => {
    it("has default class osk-breadcrumbs", () => {
      const { getByTestId } = render(
        <Breadcrumbs items={[]} data-testid="test-id" />,
      );
      expect(getByTestId("test-id")).toHaveClass("osk-breadcrumbs");
    });

    it("ordered list has default class osk-breadcrumbs__container", () => {
      const { container } = render(<Breadcrumbs items={[]} />);
      const orderList = container.querySelector("ol");
      expect(orderList).toBeInTheDocument();
      expect(orderList).toHaveClass("osk-breadcrumbs__container");
    });

    it("renders empty breadcrumbs when items array is empty", () => {
      const { container } = render(<Breadcrumbs items={[]} />);
      const listItems = container.querySelectorAll("li");
      expect(listItems).toHaveLength(0);
    });

    it("renders nav element with proper semantic structure", () => {
      const { container } = render(<Breadcrumbs items={[]} />);
      const nav = container.querySelector("nav");
      const ol = container.querySelector("ol");
      expect(nav).toBeInTheDocument();
      expect(ol).toBeInTheDocument();
      expect(nav).toContainElement(ol);
    });
  });

  describe("passed props", () => {
    it("passes other props", () => {
      const { getByTestId } = render(
        <Breadcrumbs data-testid="test" items={[]} />,
      );
      expect(getByTestId("test")).toBeInTheDocument();
    });

    it("has additional class when className is set", () => {
      const { getByTestId } = render(
        <Breadcrumbs data-testid="test-id" className="test-class" items={[]} />,
      );
      expect(getByTestId("test-id")).toHaveClass("osk-breadcrumbs");
      expect(getByTestId("test-id")).toHaveClass("test-class");
    });

    it("nav element has aria-label attribute when label prop is passed", () => {
      const { container } = render(
        <Breadcrumbs data-testid="test" items={[]} label="test-label" />,
      );
      expect(container.querySelector("nav").getAttribute("aria-label")).toBe(
        "test-label",
      );
    });

    it("combines multiple CSS classes correctly", () => {
      const { getByTestId } = render(
        <Breadcrumbs
          data-testid="test-id"
          className="custom-class another-class"
          items={[]}
        />,
      );
      expect(getByTestId("test-id")).toHaveClass("osk-breadcrumbs");
      expect(getByTestId("test-id")).toHaveClass("custom-class");
      expect(getByTestId("test-id")).toHaveClass("another-class");
    });

    it("renders correct number of breadcrumb items", () => {
      const { container } = render(<Breadcrumbs items={itemsArr} />);
      const listItems = container.querySelectorAll("li");
      expect(listItems).toHaveLength(itemsArr.length);
    });

    itemsArr.map(({ url, text }, index) => {
      it(`renders BreadcrumbItem with text ${text} ${
        url && index !== itemsArr.length - 1
          ? "inside anchor element with url " + url
          : ""
      }`, () => {
        const { container } = render(<Breadcrumbs items={itemsArr} />);
        const listElements = container.querySelectorAll("li");
        expect(listElements[index].textContent).toBe(text);

        // Only non-last items with URL should have anchors
        if (url && index !== itemsArr.length - 1) {
          expect(listElements[index].children[0].getAttribute("href")).toBe(
            url,
          );
        }
      });
    });

    it("last item does not render as anchor element", () => {
      const items = [
        { url: "/test1", text: "test1-text" },
        { url: "/test2", text: "test2-text" },
        { url: "/test3", text: "test3-text" },
      ];
      const { container } = render(<Breadcrumbs items={items} />);
      const listItems = container.querySelectorAll("li");
      const lastItem = listItems[listItems.length - 1];

      expect(lastItem).toHaveAttribute("aria-current", "page");
      expect(lastItem.querySelector("a")).not.toBeInTheDocument();
    });

    it("marks last item as current page even without URL", () => {
      const items = [
        { url: "/test1", text: "test1-text" },
        { text: "test2-test" },
      ];
      const { container } = render(<Breadcrumbs items={items} />);
      const listItems = container.querySelectorAll("li");
      expect(listItems[listItems.length - 1].textContent).toBe("test2-test");
      expect(listItems[listItems.length - 1].querySelector("a")).toBeNull();
    });

    it("renders all items with correct text content", () => {
      const { container } = render(<Breadcrumbs items={complexItemsArr} />);
      const listElements = container.querySelectorAll("li");

      complexItemsArr.forEach((item, index) => {
        expect(listElements[index].textContent).toBe(item.text);
      });
    });

    it("renders anchor elements with correct href attributes", () => {
      const { container } = render(<Breadcrumbs items={complexItemsArr} />);
      const anchors = container.querySelectorAll("a");

      // Should have 3 anchors (last item has no URL)
      expect(anchors).toHaveLength(3);

      anchors.forEach((anchor, index) => {
        expect(anchor.getAttribute("href")).toBe(complexItemsArr[index].url);
      });
    });

    it("applies correct CSS classes to anchor elements", () => {
      const { container } = render(<Breadcrumbs items={complexItemsArr} />);
      const anchors = container.querySelectorAll("a");

      // Only non-last items should have anchors (last item is current page, plain text)
      anchors.forEach((anchor) => {
        expect(anchor).toHaveClass("osk-breadcrumbs__link");
      });
    });
  });

  describe("accessibility", () => {
    it("has proper navigation structure", () => {
      const { container } = render(
        <Breadcrumbs items={complexItemsArr} label="Navigácia" />,
      );

      const nav = container.querySelector("nav");
      const ol = container.querySelector("ol");

      expect(nav).toHaveAttribute("aria-label", "Navigácia");
      expect(ol).toBeInTheDocument();
      expect(nav).toContainElement(ol);
    });

    it('last item has aria-current="page" and is not an anchor', () => {
      const itemsWithLastUrl = [
        { url: "/home", text: "Domov" },
        { url: "/current", text: "Aktuálna stránka" },
      ];

      const { container } = render(<Breadcrumbs items={itemsWithLastUrl} />);
      const listElements = container.querySelectorAll("li");
      const lastItem = listElements[listElements.length - 1];

      expect(lastItem).toHaveAttribute("aria-current", "page");
      expect(lastItem.querySelector("a")).not.toBeInTheDocument();
    });

    it("last item without URL is still marked as current", () => {
      const { container } = render(<Breadcrumbs items={complexItemsArr} />);
      const listElements = container.querySelectorAll("li");
      const lastItem = listElements[listElements.length - 1];

      // Last item should be the current page even without URL
      expect(lastItem.textContent).toBe("Mobilné telefóny");
    });
  });

  describe("edge cases", () => {
    it("handles single item correctly", () => {
      const singleItem = [{ text: "Domov" }];
      const { container } = render(<Breadcrumbs items={singleItem} />);

      const listItems = container.querySelectorAll("li");
      expect(listItems).toHaveLength(1);
      expect(listItems[0].textContent).toBe("Domov");
    });

    it("handles single item with URL correctly", () => {
      const singleItemWithUrl = [{ url: "/home", text: "Domov" }];
      const { container } = render(<Breadcrumbs items={singleItemWithUrl} />);

      const listItems = container.querySelectorAll("li");
      const anchor = container.querySelector("a");

      expect(listItems).toHaveLength(1);
      // Single item is the last (current) item, so no anchor
      expect(anchor).not.toBeInTheDocument();
      expect(listItems[0]).toHaveAttribute("aria-current", "page");
    });

    it("handles items with special characters in text", () => {
      const specialItems = [
        { url: "/test", text: "Test & More" },
        { text: "Special: Characters!" },
      ];

      const { container } = render(<Breadcrumbs items={specialItems} />);
      const listItems = container.querySelectorAll("li");

      expect(listItems[0].textContent).toBe("Test & More");
      expect(listItems[1].textContent).toBe("Special: Characters!");
    });

    it("handles items with empty text gracefully", () => {
      const emptyTextItems = [
        { url: "/test", text: "" },
        { text: "Valid text" },
      ];

      const { container } = render(<Breadcrumbs items={emptyTextItems} />);
      const listItems = container.querySelectorAll("li");

      expect(listItems[0].textContent).toBe("");
      expect(listItems[1].textContent).toBe("Valid text");
    });
  });

  describe("interaction", () => {
    it("anchor elements are clickable", async () => {
      const { container } = render(<Breadcrumbs items={complexItemsArr} />);

      const anchors = container.querySelectorAll("a");
      expect(anchors).toHaveLength(3);

      // Test that anchors are focusable
      for (const anchor of anchors) {
        expect(anchor).toHaveAttribute("href");
        expect(anchor).not.toBeDisabled();
      }
    });

    it("maintains proper tab order", () => {
      const { container } = render(<Breadcrumbs items={complexItemsArr} />);
      const anchors = container.querySelectorAll("a");

      // All anchors should be focusable
      anchors.forEach((anchor) => {
        expect(anchor).toHaveAttribute("href");
      });
    });
  });
});
