"use client";

import {
  useEffect,
  useRef,
  useState,
  type ReactNode,
} from "react";

type Side = "top" | "bottom";
type Align = "start" | "end" | "center";

type Props = {
  /** Élément cliquable qui toggle l'ouverture. Doit pouvoir recevoir un onClick. */
  trigger: ReactNode;
  children: ReactNode;
  side?: Side;
  align?: Align;
  /** Classe optionnelle appliquée au panneau. */
  panelClassName?: string;
  /** Classe optionnelle appliquée au wrapper du trigger. */
  triggerClassName?: string;
};

// Popover headless. Trigger en bouton wrapper, panneau positionné en
// absolute relativement au container. Ferme sur click outside + Escape.
// Pas de portail (pas nécessaire pour notre cas) — z-index élevé suffit.

export function Popover({
  trigger,
  children,
  side = "bottom",
  align = "start",
  panelClassName = "",
  triggerClassName = "",
}: Props) {
  const [open, setOpen] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!open) return;
    function onDown(e: MouseEvent) {
      if (
        containerRef.current &&
        !containerRef.current.contains(e.target as Node)
      ) {
        setOpen(false);
      }
    }
    function onKey(e: KeyboardEvent) {
      if (e.key === "Escape") setOpen(false);
    }
    document.addEventListener("mousedown", onDown);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onDown);
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);

  const sideClass = side === "top" ? "bottom-full mb-2" : "top-full mt-2";
  const alignClass =
    align === "end"
      ? "right-0"
      : align === "center"
        ? "left-1/2 -translate-x-1/2"
        : "left-0";

  return (
    <div ref={containerRef} className="relative">
      <button
        type="button"
        onClick={() => setOpen((o) => !o)}
        className={`block w-full ${triggerClassName}`}
        aria-haspopup="menu"
        aria-expanded={open}
      >
        {trigger}
      </button>
      {open && (
        <div
          role="menu"
          className={[
            "absolute z-50 min-w-44 rounded-lg border border-border bg-surface shadow-lg mf-fade-in",
            sideClass,
            alignClass,
            panelClassName,
          ].join(" ")}
          onClick={(e) => {
            // Si un descendant déclenche un onClick (ex: bouton item), on
            // ferme le popover. Permet de ne pas avoir à wrap chaque item.
            if (e.target instanceof HTMLElement && e.target.closest("[data-popover-close]")) {
              setOpen(false);
            }
          }}
        >
          {children}
        </div>
      )}
    </div>
  );
}
