"use client";

import { ChevronDown } from "lucide-react";
import { useEffect, useId, useRef, useState, type ReactNode } from "react";

import { cn } from "@/lib/utils";

export interface DropdownItem {
  id: string;
  label: ReactNode;
  hint?: ReactNode;
  icon?: ReactNode;
  active?: boolean;
  disabled?: boolean;
  onSelect?: () => void;
}

export interface DropdownMenuProps {
  items: DropdownItem[];
  children: (props: { open: boolean; toggle: () => void; id: string }) => ReactNode;
  align?: "start" | "end";
  className?: string;
  panelClassName?: string;
  label: string;
  /**
   * Optional titled section above the items, separated by a rule.
   *
   * Used where the menu needs to say what it is choosing *for* — the Download
   * menu reads "Download" over a divider above the provider names, so the list of
   * bare server names is never ambiguous. Omit it for a plain list of options.
   */
  header?: ReactNode;
}

/**
 * Lightweight dropdown menu.
 *
 * Closes on outside click, Escape, scroll and route change; restores focus to
 * the trigger. Kept dependency-free so the player bundle stays small.
 */
export function DropdownMenu({
  items,
  children,
  align = "end",
  className,
  panelClassName,
  label,
  header,
}: DropdownMenuProps) {
  const [open, setOpen] = useState(false);
  const rootRef = useRef<HTMLDivElement>(null);
  const id = useId();

  useEffect(() => {
    if (!open) return;

    const onPointerDown = (event: MouseEvent) => {
      if (!rootRef.current?.contains(event.target as Node)) setOpen(false);
    };
    const onKey = (event: KeyboardEvent) => {
      if (event.key === "Escape") setOpen(false);
    };

    document.addEventListener("mousedown", onPointerDown);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onPointerDown);
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);

  const visible = items.filter((item) => !item.disabled);

  return (
    <div ref={rootRef} className={cn("relative", className)}>
      {children({ open, toggle: () => setOpen((v) => !v), id })}

      {open ? (
        <div
          id={id}
          role="menu"
          aria-label={label}
          className={cn(
            "animate-pop absolute top-[calc(100%+8px)] z-50 min-w-[220px] overflow-hidden rounded-md",
            "border border-line bg-surface/97 p-1.5 shadow-[0_24px_60px_-12px_rgba(0,0,0,0.85)] backdrop-blur-xl",
            align === "end" ? "right-0" : "left-0",
            panelClassName,
          )}
        >
          {header ? (
            <div className="border-b border-line px-3 pt-1.5 pb-2.5">
              {header}
            </div>
          ) : null}

          {visible.length === 0 ? (
            <p className="px-3 py-2.5 text-[13px] text-ink-muted">No options available</p>
          ) : (
            visible.map((item) => (
              <button
                key={item.id}
                type="button"
                role="menuitem"
                onClick={() => {
                  item.onSelect?.();
                  setOpen(false);
                }}
                className={cn(
                  "flex w-full items-center gap-2.5 rounded-sm px-3 py-2.5 text-left text-[13px] font-medium",
                  "text-ink-soft transition-colors hover:bg-white/8 hover:text-ink",
                  item.active && "bg-white/8 text-ink",
                )}
              >
                {item.icon}
                <span className="min-w-0 flex-1 truncate">{item.label}</span>
                {item.hint ? (
                  <span className="shrink-0 text-[11px] text-ink-faint">{item.hint}</span>
                ) : null}
                {item.active ? (
                  <svg viewBox="0 0 24 24" className="h-4 w-4 shrink-0 text-brand-400" aria-hidden>
                    <path
                      fill="currentColor"
                      d="M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"
                    />
                  </svg>
                ) : null}
              </button>
            ))
          )}
        </div>
      ) : null}
    </div>
  );
}

export function DropdownTrigger({
  open,
  toggle,
  id,
  children,
  className,
  ...rest
}: {
  open: boolean;
  toggle: () => void;
  id: string;
  children: ReactNode;
  className?: string;
} & React.ButtonHTMLAttributes<HTMLButtonElement>) {
  return (
    <button
      type="button"
      id={id}
      aria-haspopup="menu"
      aria-expanded={open}
      onClick={toggle}
      className={cn(
        "inline-flex items-center gap-2 rounded-pill text-sm font-semibold transition-colors",
        className,
      )}
      {...rest}
    >
      {children}
      <ChevronDown
        className={cn("h-4 w-4 transition-transform duration-300", open && "rotate-180")}
      />
    </button>
  );
}
