"use client";

// A dropdown that renders into <body> instead of next to its trigger.
//
// Why: `.dash-topbar` is `position: sticky; z-index: 20`, which opens a stacking context — any
// popover inside it is trapped at the topbar's level no matter how high its own z-index goes.
// Module content can legitimately stack above that (the vendored photo-gallery SDK reaches 1400),
// so an in-topbar dropdown gets covered. Portalling to <body> takes the popover out of that
// context entirely, which is the only fix that survives a module raising its own z-index later.
//
// The panel is positioned from the trigger's viewport rect and closes on scroll/resize rather than
// tracking it — a menu that follows the page while you scroll reads as broken.

import { useEffect, useLayoutEffect, useRef, useState, type ReactNode, type RefObject } from "react";
import { createPortal } from "react-dom";

/** Above the vendored gallery SDK's maximum (1400) so module chrome can never cover a global menu. */
const POPOVER_Z = 2000;

export function AnchoredPopover({
  anchorRef,
  open,
  onClose,
  children,
  width = 260,
}: {
  anchorRef: RefObject<HTMLElement | null>;
  open: boolean;
  onClose: () => void;
  children: ReactNode;
  width?: number;
}) {
  const [pos, setPos] = useState<{ top: number; left: number } | null>(null);
  const panelRef = useRef<HTMLDivElement>(null);

  // Measure before paint so the panel never flashes at the wrong spot.
  useLayoutEffect(() => {
    if (!open) return;
    const el = anchorRef.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    // Right-align to the trigger, clamped so it can't run off either edge.
    const left = Math.max(8, Math.min(r.right - width, window.innerWidth - width - 8));
    setPos({ top: r.bottom + 8, left });
  }, [open, anchorRef, width]);

  useEffect(() => {
    if (!open) return;
    const close = () => onClose();
    const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); };
    // `true` = capture, so a scroll inside any nested container closes it too.
    window.addEventListener("scroll", close, true);
    window.addEventListener("resize", close);
    window.addEventListener("keydown", onKey);
    return () => {
      window.removeEventListener("scroll", close, true);
      window.removeEventListener("resize", close);
      window.removeEventListener("keydown", onKey);
    };
  }, [open, onClose]);

  if (!open || !pos || typeof document === "undefined") return null;

  return createPortal(
    <>
      <div style={{ position: "fixed", inset: 0, zIndex: POPOVER_Z }} onMouseDown={onClose} />
      <div
        ref={panelRef}
        role="menu"
        className="tm-menu-pop"
        style={{ position: "fixed", top: pos.top, left: pos.left, width, zIndex: POPOVER_Z + 1, right: "auto" }}
        onMouseDown={(e) => e.stopPropagation()}
      >
        {children}
      </div>
    </>,
    document.body,
  );
}
