"use client";

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

interface PopoverPosition {
  top: number;
  left: number;
}

interface UsePopoverPositionOptions {
  offset?: number;
  estimatedWidth?: number;
  estimatedHeight?: number;
}
export function usePopoverPosition(
  triggerRef: RefObject<HTMLElement | null>,
  open: boolean,
  popoverRef: RefObject<HTMLElement | null>,
  options: UsePopoverPositionOptions = {}
) {
  const { offset = 6, estimatedWidth = 260, estimatedHeight = 160 } = options;
  const [position, setPosition] = useState<PopoverPosition | null>(null);

  const recalculate = useCallback(() => {
    const trigger = triggerRef.current;
    if (!trigger) return;

    const triggerRect = trigger.getBoundingClientRect();
    const popoverEl = popoverRef.current;
    const width = popoverEl?.offsetWidth || estimatedWidth;
    const height = popoverEl?.offsetHeight || estimatedHeight;

    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;
    const margin = 8;
    let left = triggerRect.left;
    if (left + width > viewportWidth - margin) {
      left = triggerRect.right - width;
    }
    left = Math.max(margin, Math.min(left, viewportWidth - width - margin));
    const spaceBelow = viewportHeight - triggerRect.bottom;
    const spaceAbove = triggerRect.top;
    let top: number;
    if (spaceBelow >= height + offset || spaceBelow >= spaceAbove) {
      top = triggerRect.bottom + offset;
      top = Math.min(top, viewportHeight - height - margin);
    } else {
      top = triggerRect.top - height - offset;
    }
    top = Math.max(margin, top);

    setPosition({ top, left });
  }, [triggerRef, popoverRef, offset, estimatedWidth, estimatedHeight]);

  useLayoutEffect(() => {
    if (!open) {
      setPosition(null);
      return;
    }
    recalculate();
    const raf = requestAnimationFrame(recalculate);

    const handle = () => recalculate();
    window.addEventListener("resize", handle);
    window.addEventListener("scroll", handle, true);

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("resize", handle);
      window.removeEventListener("scroll", handle, true);
    };
  }, [open, recalculate]);

  return position;
}

interface PopoverPortalProps {
  open: boolean;
  position: PopoverPosition | null;
  popoverRef: RefObject<HTMLElement | null>;
  children: React.ReactNode;
  className?: string;
}

export function PopoverPortal({
  open,
  position,
  popoverRef,
  children,
  className = "",
}: PopoverPortalProps) {
  const wrapperRef = useRef<HTMLDivElement>(null);
  // useLayoutEffect(() => {
  //   if (!open) return;
  //   const node = wrapperRef.current;
  //   if (!node) return;

  //   const stop = (e: Event) => e.stopPropagation();
  //   node.addEventListener("mousedown", stop, true);
  //   node.addEventListener("click", stop, true);
  //   node.addEventListener("pointerdown", stop, true);

  //   return () => {
  //     node.removeEventListener("mousedown", stop, true);
  //     node.removeEventListener("click", stop, true);
  //     node.removeEventListener("pointerdown", stop, true);
  //   };
  // }, [open]);

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

  return createPortal(
    <div
      ref={(node) => {
        wrapperRef.current = node;
        (popoverRef as RefObject<HTMLDivElement | null>).current = node;
      }}
      data-popover-root=""
      className={`fixed z-999 ${className}`}
      style={{
        top: position?.top ?? -99999,
        left: position?.left ?? -99999,
        visibility: position ? "visible" : "hidden",
      }}
    >
      {children}
    </div>,
    document.body
  );
}
