import React, { CSSProperties } from "react";

import { MaterialIcon } from "@shared/components/material-icon";
import { Text } from "@shared/components/text";
import { Button } from "@shared/contentful/blocks/button";
import { ButtonProps as ContentfulButtonProps } from "@shared/contentful/blocks/button/types";
import { useOutsideClick } from "@shared/hooks/use-outside-click";
import { cx } from "@shared/utils";

type ComponentButtonGroup = {
  anchorId?: string | null;
  title?: string | null;
  items?: { items?: ContentfulButtonProps[] | null } | null;
};

type Link = ContentfulButtonProps | ComponentButtonGroup;

type LinkGroupsProps = {
  link?: Link;
  anchorName: string;
  /**
   * Tailwind text-color class to apply to the top-level link/group
   * label. Lets the parent navbar invert text color (e.g. `text-white`)
   * when rendered on a dark background. Submenu items keep their
   * default `text-text-link` so they remain readable on the white
   * popover background.
   */
  linkColorClassName?: string;
};

const isButton = (link: Link): link is ContentfulButtonProps => {
  // If your group never has `href`, this is a simple and effective guard
  return typeof (link as ContentfulButtonProps).href === "string";
};

export const DesktopLinkGroups: React.FC<LinkGroupsProps> = ({
  link,
  anchorName,
  linkColorClassName,
}) => {
  const [isOpen, setIsOpen] = React.useState(false);

  const ref = React.useRef<HTMLDivElement>(null);
  useOutsideClick(ref, () => setIsOpen(false));

  if (!link) return null;

  // Single button
  if (isButton(link)) {
    return (
      <Button
        key={`submenu-link-btn-${link.anchorId}`}
        {...link}
        linkClassName={cx(
          "body3 flex items-center h-full",
          linkColorClassName || "text-text"
        )}
        linkVariant="unstyled"
      />
    );
  }

  // Group
  const { anchorId, title, items } = link;
  const subMenu = Array.isArray(items?.items) ? items!.items! : [];
  const fullAnchorName = `--link-anchor-${anchorName}`;

  return (
    <div
      className="relative h-full"
      style={{ anchorName: fullAnchorName } as CSSProperties}
      ref={ref}
    >
      <Button
        onClick={() => setIsOpen(prev => !prev)}
        aria-expanded={isOpen}
        buttonClassName={cx(
          "group body3 flex items-center h-full",
          linkColorClassName || "text-text"
        )}
        key={anchorId}
        showButtonAs="unstyled"
      >
        <Text as="span" className="group-hover:underline">
          {title ?? null}
        </Text>
        <MaterialIcon
          weight="200"
          size={24}
          className="group-hover:opacity-50 text-icon-secondary"
          name={isOpen ? "keyboard_arrow_up" : "keyboard_arrow_down"}
        />
      </Button>

      <div
        className={cx(
          "shadow-navDrop fixed z-[1001] min-w-44 rounded-input-poppers border border-border bg-bg",
          "transition-[opacity,transform] ease-out",
          isOpen && subMenu.length > 0
            ? "pointer-events-auto translate-y-0 opacity-100 duration-75"
            : "pointer-events-none -translate-y-2 opacity-0 duration-0"
        )}
        style={
          {
            positionAnchor: fullAnchorName,
            top: "anchor(bottom)",
            left: "calc((anchor(left) + anchor(right)) / 2)",
            translate: "-50% 0",
          } as CSSProperties
        }
      >
        <ul
          className="flex flex-col gap-2 py-2"
          onClick={event => {
            // Close the popup when a submenu link is clicked.
            // Required for Pages Router where this component persists across
            // client-side navigations and `isOpen` would otherwise stay true.
            const target = event.target as HTMLElement | null;
            if (target?.closest("a")) {
              setIsOpen(false);
            }
          }}
        >
          {subMenu.map((site, index) => {
            return (
              <li key={`submenu-link-${index}`} className="submenu-link type1">
                <Button
                  {...site}
                  linkVariant="unstyled"
                  linkClassName="body3 px-4 hover:bg-bg-surface-hover flex items-center w-full h-11 text-text-link"
                />
              </li>
            );
          })}
        </ul>
      </div>
    </div>
  );
};
