// src/components/storage/ActionMenuPortal.jsx
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";

function clamp(n, min, max) {
  return Math.max(min, Math.min(max, n));
}

function useOutsidePointerDown(ref, handler, when = true) {
  useEffect(() => {
    if (!when) return;
    const onDown = (e) => {
      if (!ref.current) return;
      if (ref.current.contains(e.target)) return;
      handler?.(e);
    };
    document.addEventListener("pointerdown", onDown);
    return () => document.removeEventListener("pointerdown", onDown);
  }, [ref, handler, when]);
}

export default function ActionMenuPortal({
  open,
  rect,
  onClose,
  children,
  width = 280,
  offset = 8,
}) {
  const menuRef = useRef(null);
  const [pos, setPos] = useState({ top: 0, left: 0 });

  useOutsidePointerDown(menuRef, () => onClose?.(), open);

  useEffect(() => {
    if (!open) return;
    const onKey = (e) => e.key === "Escape" && onClose?.();
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open, onClose]);

  useLayoutEffect(() => {
    if (!open || !rect) return;

    const calc = () => {
      const vh = window.innerHeight;
      const vw = window.innerWidth;

      const menuW = width;
      const menuH = menuRef.current?.offsetHeight || 240;

      let top = rect.bottom + offset;
      let left = rect.right - menuW;

      if (top + menuH > vh - 8) top = rect.top - menuH - offset;

      top = clamp(top, 8, vh - menuH - 8);
      left = clamp(left, 8, vw - menuW - 8);

      setPos({ top: top + window.scrollY, left: left + window.scrollX });
    };

    calc();
    window.addEventListener("resize", calc);
    window.addEventListener("scroll", calc, true);
    return () => {
      window.removeEventListener("resize", calc);
      window.removeEventListener("scroll", calc, true);
    };
  }, [open, rect, width, offset]);

  if (!open || !rect) return null;

  return createPortal(
    <div
      ref={menuRef}
      style={{ position: "absolute", top: pos.top, left: pos.left, width }}
      className="pointer-events-auto z-[999999] rounded-2xl shadow-xl border border-black/5 dark:border-white/10 bg-[#f2f2f2] dark:bg-[#001F3F]"
      onPointerDown={(e) => e.stopPropagation()}
      onClick={(e) => e.stopPropagation()}
    >
      <div className="p-2">{children}</div>
    </div>,
    document.body
  );
}
