import { useEffect, type RefObject } from "react";

/** While `active`, close (call `onClose`) on Escape or a mousedown outside ALL of the given
 * element(s). The reusable half of the popover/dropdown pattern that several components each
 * hand-rolled; positioning stays with the caller (it varies per popover). Pass the panel ref
 * (and optionally a trigger ref so clicking the trigger doesn't immediately re-close). */
export function useDismiss(
  active: boolean,
  onClose: () => void,
  refs: RefObject<HTMLElement | null> | RefObject<HTMLElement | null>[],
): void {
  useEffect(() => {
    if (!active) return;
    const list = Array.isArray(refs) ? refs : [refs];
    const onDown = (e: MouseEvent) => {
      const target = e.target as Node;
      if (!list.some((r) => r.current?.contains(target))) onClose();
    };
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") {
        // Stop the same Escape from also reaching a player's window-level listener underneath —
        // this document listener bubbles first, so one Escape closes only this popover, not the
        // popover AND the player behind it. (U-C quick-fix.)
        //
        // KNOWN LIMITATION (accepted, → R8 popover-platform): because this is a blanket
        // stopPropagation, a PlexPlayer settings/tracks menu open DURING an auto-skip countdown
        // swallows the Escape that would otherwise ALSO cancel the skip — Escape closes the menu,
        // and the skip proceeds. Properly fixing this needs the shared layer-registry R8 builds
        // (topmost-only dispatch), not a broad stopPropagation.
        e.stopPropagation();
        onClose();
      }
    };
    document.addEventListener("mousedown", onDown);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onDown);
      document.removeEventListener("keydown", onKey);
    };
    // Matches the original effects: (re)subscribe only when open/closed toggles. Refs are
    // stable and onClose is read fresh from this run's closure.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [active]);
}
