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

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

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

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

jest.mock("@shared/contentful/blocks/button", () => ({
  Button: ({
    children,
    buttonClassName,
    onClick,
    linkClassName,
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    showButtonAs,
    ...rest
  }: any) => (
    <button
      data-testid="button"
      className={buttonClassName || linkClassName}
      onClick={onClick}
      aria-expanded={rest["aria-expanded"]}
    >
      {children || rest.buttonLabel}
    </button>
  ),
}));

let outsideClickCallback: (() => void) | null = null;
jest.mock("@shared/hooks/use-outside-click", () => ({
  useOutsideClick: (_ref: any, cb: () => void) => {
    outsideClickCallback = cb;
  },
}));

jest.mock("@shared/utils", () => ({
  cx: (...args: any[]) => args.filter(Boolean).join(" "),
}));

describe("DesktopLinkGroups", () => {
  it("renders nothing when link is undefined", () => {
    const { container } = render(
      <DesktopLinkGroups anchorName="test" link={undefined} />
    );
    expect(container.innerHTML).toBe("");
  });

  it("renders single Button when link is a button (has href)", () => {
    const link = {
      href: "/products",
      buttonLabel: "Products",
      anchorId: "prod",
    };
    render(<DesktopLinkGroups anchorName="nav-0" link={link as any} />);
    expect(screen.getByTestId("button")).toHaveTextContent("Products");
  });

  describe("Group rendering", () => {
    const groupLink = {
      anchorId: "group-1",
      title: "My Account",
      items: {
        items: [
          { buttonLabel: "Profile", href: "/profile", anchorId: "p1" },
          { buttonLabel: "Settings", href: "/settings", anchorId: "p2" },
        ],
      },
    };

    it("renders group title button", () => {
      render(
        <DesktopLinkGroups anchorName="account-0" link={groupLink as any} />
      );
      expect(screen.getByText("My Account")).toBeInTheDocument();
    });

    it("renders dropdown arrow icon (down when closed)", () => {
      render(
        <DesktopLinkGroups anchorName="account-0" link={groupLink as any} />
      );
      expect(
        screen.getByTestId("icon-keyboard_arrow_down")
      ).toBeInTheDocument();
    });

    it("toggles open state and shows up arrow when open", () => {
      render(
        <DesktopLinkGroups anchorName="account-0" link={groupLink as any} />
      );
      const toggleBtn = screen.getAllByTestId("button")[0];
      fireEvent.click(toggleBtn);
      expect(screen.getByTestId("icon-keyboard_arrow_up")).toBeInTheDocument();
    });

    it("renders submenu items when open", () => {
      render(
        <DesktopLinkGroups anchorName="account-0" link={groupLink as any} />
      );
      const toggleBtn = screen.getAllByTestId("button")[0];
      fireEvent.click(toggleBtn);
      expect(screen.getByText("Profile")).toBeInTheDocument();
      expect(screen.getByText("Settings")).toBeInTheDocument();
    });

    it("closes when toggled again", () => {
      render(
        <DesktopLinkGroups anchorName="account-0" link={groupLink as any} />
      );
      const toggleBtn = screen.getAllByTestId("button")[0];
      fireEvent.click(toggleBtn);
      fireEvent.click(toggleBtn);
      expect(
        screen.getByTestId("icon-keyboard_arrow_down")
      ).toBeInTheDocument();
    });

    it("renders null title when title is missing", () => {
      const noTitleLink = { ...groupLink, title: null };
      render(
        <DesktopLinkGroups anchorName="account-0" link={noTitleLink as any} />
      );
      // Should still render without error
      expect(screen.getAllByTestId("button")[0]).toBeInTheDocument();
    });

    it("handles empty items array", () => {
      const emptyItems = { ...groupLink, items: { items: [] } };
      render(
        <DesktopLinkGroups anchorName="account-0" link={emptyItems as any} />
      );
      const toggleBtn = screen.getAllByTestId("button")[0];
      fireEvent.click(toggleBtn);
      // No submenu links rendered
      expect(screen.getAllByTestId("button")).toHaveLength(1);
    });

    it("handles null items", () => {
      const nullItems = { ...groupLink, items: null };
      render(
        <DesktopLinkGroups anchorName="account-0" link={nullItems as any} />
      );
      const toggleBtn = screen.getAllByTestId("button")[0];
      fireEvent.click(toggleBtn);
      expect(screen.getAllByTestId("button")).toHaveLength(1);
    });

    it("closes when a submenu anchor link is clicked", () => {
      render(
        <DesktopLinkGroups anchorName="account-0" link={groupLink as any} />
      );
      const toggleBtn = screen.getAllByTestId("button")[0];
      fireEvent.click(toggleBtn);
      // Simulate clicking an anchor within the submenu ul
      const submenuList = screen.getByRole("list");
      const anchor = document.createElement("a");
      anchor.href = "/profile";
      submenuList.appendChild(anchor);
      fireEvent.click(anchor);
      // After click, arrow should be down (closed)
      expect(
        screen.getByTestId("icon-keyboard_arrow_down")
      ).toBeInTheDocument();
    });

    it("does not close when non-anchor element is clicked in submenu", () => {
      render(
        <DesktopLinkGroups anchorName="account-0" link={groupLink as any} />
      );
      const toggleBtn = screen.getAllByTestId("button")[0];
      fireEvent.click(toggleBtn);
      const submenuList = screen.getByRole("list");
      // Click on a non-anchor element
      fireEvent.click(submenuList);
      // Should still be open
      expect(screen.getByTestId("icon-keyboard_arrow_up")).toBeInTheDocument();
    });

    it("closes when outside click is triggered", () => {
      render(
        <DesktopLinkGroups anchorName="account-0" link={groupLink as any} />
      );
      const toggleBtn = screen.getAllByTestId("button")[0];
      fireEvent.click(toggleBtn);
      // Should be open
      expect(screen.getByTestId("icon-keyboard_arrow_up")).toBeInTheDocument();
      // Trigger outside click callback
      act(() => {
        outsideClickCallback!();
      });
      // Should close
      expect(
        screen.getByTestId("icon-keyboard_arrow_down")
      ).toBeInTheDocument();
    });
  });
});
