import { useState, useRef, useLayoutEffect } from "react";
const useMenuPosition = ({
  isOpen,
  triggerRef,
  menuRef,
  withPortal = false,
  dropdownPosition
}) => {
  const [menuStyle, setMenuStyle] = useState({ opacity: 0 });
  const positionUpdateRef = useRef(null);
  const lastPositionRef = useRef(null);
  const isHiddenRef = useRef(true);
  useLayoutEffect(() => {
    if (!isOpen || !triggerRef.current) {
      if (!isHiddenRef.current) {
        setMenuStyle({ opacity: 0 });
        isHiddenRef.current = true;
      }
      return;
    }
    isHiddenRef.current = false;
    const calculatePosition = () => {
      if (!triggerRef.current) return null;
      const triggerRect = triggerRef.current.getBoundingClientRect();
      const viewportWidth = window.innerWidth;
      const viewportHeight = window.innerHeight;
      const scrollX = window.scrollX || document.documentElement.scrollLeft;
      const scrollY = window.scrollY || document.documentElement.scrollTop;
      let menuHeight = 320;
      if (menuRef == null ? void 0 : menuRef.current) {
        const menuRect = menuRef.current.getBoundingClientRect();
        menuHeight = menuRect.height || 320;
      }
      const menuWidth = triggerRect.width;
      const spacing = 6;
      const viewportTopOffset = 64;
      const spaceBelow = viewportHeight - triggerRect.bottom;
      const spaceAbove = triggerRect.top - viewportTopOffset;
      let position = "bottom";
      if (dropdownPosition === "top" || dropdownPosition === "bottom") {
        position = dropdownPosition;
      } else {
        if (spaceBelow >= menuHeight + spacing) {
          position = "bottom";
        } else if (spaceAbove >= menuHeight + spacing) {
          position = "top";
        } else {
          position = spaceBelow >= spaceAbove ? "bottom" : "top";
        }
      }
      let top = 0;
      let left = 0;
      if (withPortal) {
        if (position === "bottom") {
          top = triggerRect.bottom + scrollY + spacing;
        } else {
          top = triggerRect.top + scrollY - menuHeight - spacing;
        }
        left = triggerRect.left + scrollX;
        top = Math.max(viewportTopOffset + scrollY, top);
      } else {
        if (position === "bottom") {
          top = triggerRect.height + spacing - 4;
        } else {
          top = -menuHeight - spacing;
        }
        left = 0;
        const absoluteY = triggerRect.top;
        const minTopRelative = viewportTopOffset - absoluteY;
        top = Math.max(minTopRelative, top);
      }
      if (withPortal) {
        let adjustedLeft = left - scrollX;
        if (adjustedLeft + menuWidth > viewportWidth) {
          adjustedLeft = Math.max(0, viewportWidth - menuWidth - 10);
        }
        if (adjustedLeft < 0) {
          adjustedLeft = 10;
        }
        left = adjustedLeft + scrollX;
      }
      return { top, left, width: menuWidth, position };
    };
    const applyPosition = (newPosition) => {
      const lastPos = lastPositionRef.current;
      if (!lastPos || lastPos.top !== newPosition.top || lastPos.left !== newPosition.left || lastPos.width !== newPosition.width || lastPos.position !== newPosition.position) {
        lastPositionRef.current = {
          top: newPosition.top,
          left: newPosition.left,
          width: newPosition.width,
          position: newPosition.position
        };
        const style = {
          top: newPosition.top,
          width: newPosition.width + "px",
          minWidth: newPosition.width + "px",
          opacity: 1
        };
        if (withPortal) {
          style.left = newPosition.left;
          style.position = "absolute";
        }
        setMenuStyle(style);
      }
    };
    const updatePosition = () => {
      if (positionUpdateRef.current !== null) {
        cancelAnimationFrame(positionUpdateRef.current);
      }
      positionUpdateRef.current = requestAnimationFrame(() => {
        const newPosition = calculatePosition();
        if (newPosition) {
          applyPosition(newPosition);
        }
        positionUpdateRef.current = null;
      });
    };
    const initialPos = calculatePosition();
    if (initialPos) {
      applyPosition(initialPos);
    }
    let resizeObserver = null;
    if (typeof ResizeObserver !== "undefined" && triggerRef.current) {
      resizeObserver = new ResizeObserver(() => {
        updatePosition();
      });
      resizeObserver.observe(triggerRef.current);
    }
    let resizeFrame = null;
    const handleResize = () => {
      if (resizeFrame !== null) return;
      resizeFrame = requestAnimationFrame(() => {
        updatePosition();
        resizeFrame = null;
      });
    };
    let scrollFrame = null;
    const handleScroll = () => {
      if (scrollFrame !== null) return;
      scrollFrame = requestAnimationFrame(() => {
        updatePosition();
        scrollFrame = null;
      });
    };
    const scrollableParents = [];
    let parent = triggerRef.current.parentElement;
    while (parent) {
      const style = window.getComputedStyle(parent);
      const overflowY = style.overflowY;
      const overflowX = style.overflowX;
      if (overflowY === "auto" || overflowY === "scroll" || overflowX === "auto" || overflowX === "scroll") {
        scrollableParents.push(parent);
      }
      parent = parent.parentElement;
    }
    scrollableParents.forEach((scrollableParent) => {
      scrollableParent.addEventListener("scroll", handleScroll, { passive: true });
    });
    window.addEventListener("resize", handleResize, { passive: true });
    window.addEventListener("scroll", handleScroll, { passive: true, capture: true });
    return () => {
      if (positionUpdateRef.current !== null) {
        cancelAnimationFrame(positionUpdateRef.current);
        positionUpdateRef.current = null;
      }
      if (resizeFrame !== null) {
        cancelAnimationFrame(resizeFrame);
      }
      if (scrollFrame !== null) {
        cancelAnimationFrame(scrollFrame);
      }
      if (resizeObserver) {
        resizeObserver.disconnect();
      }
      scrollableParents.forEach((scrollableParent) => {
        scrollableParent.removeEventListener("scroll", handleScroll);
      });
      window.removeEventListener("resize", handleResize);
      window.removeEventListener("scroll", handleScroll, true);
      lastPositionRef.current = null;
    };
  }, [isOpen, triggerRef, menuRef, withPortal, dropdownPosition]);
  return menuStyle;
};
export {
  useMenuPosition
};
