import "@testing-library/jest-dom";

import React from "react";
import { BreadcrumbNavigation } from "./index";

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

jest.mock("@shared/components/material-icon", () => ({
  MaterialIcon: ({ name, className }: any) => (
    <span data-testid="material-icon" className={className}>
      {name}
    </span>
  ),
}));

jest.mock("@shared/components/text", () => ({
  Text: ({ as: Tag = "span", children, className }: any) => (
    <Tag className={className}>{children}</Tag>
  ),
}));

const baseLinks = [
  { buttonLabel: "Home", href: "/" },
  { buttonLabel: "Blog", href: "/blog" },
  { buttonLabel: "Current Page" },
];

describe("BreadcrumbNavigation", () => {
  it("renders nothing when links is empty", () => {
    const { container } = render(<BreadcrumbNavigation links={[]} />);
    expect(container.querySelector("nav")).not.toBeInTheDocument();
  });

  it("renders nothing when links is undefined", () => {
    const { container } = render(<BreadcrumbNavigation />);
    expect(container.querySelector("nav")).not.toBeInTheDocument();
  });

  it("renders nav with aria-label", () => {
    render(<BreadcrumbNavigation links={baseLinks} />);
    expect(screen.getByLabelText("Breadcrumb")).toBeInTheDocument();
  });

  it("renders non-last links as anchor elements with chevron", () => {
    const { container } = render(<BreadcrumbNavigation links={baseLinks} />);
    const anchors = container.querySelectorAll("a");
    expect(anchors).toHaveLength(2);
    expect(anchors[0]).toHaveAttribute("href", "/");
    expect(anchors[0]).toHaveTextContent("Home");
    expect(anchors[1]).toHaveAttribute("href", "/blog");
    const icons = screen.getAllByTestId("material-icon");
    expect(icons).toHaveLength(2);
    icons.forEach(icon => {
      expect(icon).toHaveTextContent("chevron_right");
    });
  });

  it("renders last link as Text span", () => {
    render(<BreadcrumbNavigation links={baseLinks} />);
    expect(screen.getByText("Current Page")).toBeInTheDocument();
  });

  describe("textColor", () => {
    it("applies dark text color by default", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} textColor="dark" />
      );
      const anchor = container.querySelector("a");
      expect(anchor?.className).toContain("text-text");
    });

    it("applies light text color", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} textColor="light" />
      );
      const anchor = container.querySelector("a");
      expect(anchor?.className).toContain("text-white");
    });

    it("applies mobileTextColor override", () => {
      const { container } = render(
        <BreadcrumbNavigation
          links={baseLinks}
          textColor="dark"
          mobileTextColor="light"
        />
      );
      const anchor = container.querySelector("a");
      expect(anchor?.className).toContain("text-white");
    });

    it("applies desktopTextColor override", () => {
      const { container } = render(
        <BreadcrumbNavigation
          links={baseLinks}
          textColor="dark"
          desktopTextColor="light"
        />
      );
      const anchor = container.querySelector("a");
      expect(anchor?.className).toContain("xl:text-white");
    });
  });

  describe("float prop", () => {
    it("applies absolute class when float is always", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} float="always" />
      );
      const ol = container.querySelector("ol");
      expect(ol?.className).toContain("absolute");
    });

    it("applies relative xl:absolute class when float is desktop (default)", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} float="desktop" />
      );
      const ol = container.querySelector("ol");
      expect(ol?.className).toContain("relative xl:absolute");
    });

    it("applies absolute xl:relative class when float is mobile", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} float="mobile" />
      );
      const ol = container.querySelector("ol");
      expect(ol?.className).toContain("absolute xl:relative");
    });

    it("applies relative class when float is none", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} float="none" />
      );
      const ol = container.querySelector("ol");
      expect(ol?.className).toContain("relative");
      expect(ol?.className).not.toContain("absolute");
    });

    it("applies px-7 when float is always", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} float="always" />
      );
      const ol = container.querySelector("ol");
      expect(ol?.className).toContain("px-7");
    });
  });

  describe("maxWidth", () => {
    it("applies max-w-120 class when maxWidth is true", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} maxWidth={true} />
      );
      expect(container.querySelector("nav")?.className).toContain("max-w-120");
    });

    it("applies mx-auto without max-w-120 when maxWidth is false", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} maxWidth={false} />
      );
      const nav = container.querySelector("nav");
      expect(nav?.className).toContain("mx-auto");
      expect(nav?.className).not.toContain("max-w-120");
    });

    it("applies mx-5 when maxWidth is true and float is none", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} maxWidth={true} float="none" />
      );
      const nav = container.querySelector("nav");
      expect(nav?.className).toContain("mx-5");
    });

    it("does not apply mx-5 when float is not none", () => {
      const { container } = render(
        <BreadcrumbNavigation
          links={baseLinks}
          maxWidth={true}
          float="always"
        />
      );
      const nav = container.querySelector("nav");
      expect(nav?.className).not.toContain("mx-5");
    });
  });

  describe("Image handling", () => {
    it("renders image with https prefix for protocol-relative URLs", () => {
      const links = [
        {
          buttonLabel: "Home",
          href: "/",
          image: { url: "//cdn.test/img.png", alt: "Logo" },
        },
        { buttonLabel: "Current" },
      ];
      render(<BreadcrumbNavigation links={links} />);
      const img = screen.getAllByRole("img")[0];
      expect(img).toHaveAttribute("src", "https://cdn.test/img.png");
      expect(img).toHaveAttribute("alt", "Logo");
    });

    it("renders image with original URL when it does not start with //", () => {
      const links = [
        {
          buttonLabel: "Home",
          href: "/",
          image: { url: "https://cdn.test/img.png", alt: "Logo" },
        },
        { buttonLabel: "Current" },
      ];
      render(<BreadcrumbNavigation links={links} />);
      expect(screen.getAllByRole("img")[0]).toHaveAttribute(
        "src",
        "https://cdn.test/img.png"
      );
    });

    it("does not render image when url is missing", () => {
      const links = [
        { buttonLabel: "Home", href: "/", image: {} },
        { buttonLabel: "Current" },
      ];
      render(<BreadcrumbNavigation links={links} />);
      expect(screen.queryByRole("img")).not.toBeInTheDocument();
    });

    it("renders image on last breadcrumb item", () => {
      const links = [
        { buttonLabel: "Home", href: "/" },
        {
          buttonLabel: "Current",
          image: { url: "https://cdn.test/last.png", alt: "Last" },
        },
      ];
      render(<BreadcrumbNavigation links={links} />);
      expect(screen.getByRole("img")).toHaveAttribute(
        "src",
        "https://cdn.test/last.png"
      );
    });

    it("uses empty alt when image alt is not provided", () => {
      const links = [
        {
          buttonLabel: "Home",
          href: "/",
          image: { url: "https://cdn.test/img.png" },
        },
        { buttonLabel: "Current" },
      ];
      const { container } = render(<BreadcrumbNavigation links={links} />);
      const img = container.querySelector("img");
      expect(img).toHaveAttribute("alt", "");
    });
  });

  describe("default float behavior", () => {
    it("defaults float to desktop", () => {
      const { container } = render(<BreadcrumbNavigation links={baseLinks} />);
      const ol = container.querySelector("ol");
      expect(ol?.className).toContain("relative xl:absolute");
    });

    it("default textColor derives mobileTextColor as dark when float is desktop", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} textColor="light" />
      );
      // When float=desktop, resolvedMobile = "dark" (always)
      const anchor = container.querySelector("a");
      expect(anchor?.className).toContain("text-text");
    });

    it("default textColor derives desktopTextColor from textColor when float is desktop", () => {
      const { container } = render(
        <BreadcrumbNavigation links={baseLinks} textColor="light" />
      );
      const anchor = container.querySelector("a");
      expect(anchor?.className).toContain("xl:text-white");
    });
  });
});
