/**
 * use-anchor-portal — computes fixed-position rect from an anchor element
 * and provides a stable portal container mounted to document.body.
 *
 * Used by dropdown components to escape stacking context issues in
 * Shopify themes (position:relative / transform ancestors).
 *
 * Usage:
 *   const { portalStyle, wrapWithPortal } = useAnchorPortal(anchorRef);
 *   // In render: return wrapWithPortal(<YourDropdown style={portalStyle} />)
 *
 * Backward-compat: if anchorRef is undefined or has no current element,
 * wrapWithPortal returns the node as-is and portalStyle is undefined.
 */
import { useState, useEffect, useCallback, useRef } from "react";
import ReactDOM from "react-dom";
/**
 * @param anchorRef   Ref to the element the dropdown should appear under.
 * @param dropdownHeight  Estimated dropdown height for flip-up logic (px, default 400).
 * @param zIndex      Optional z-index to include in the computed style.
 */
export function useAnchorPortal(anchorRef, dropdownHeight = 400, zIndex) {
    const [portalStyle, setPortalStyle] = useState(undefined);
    const [dataPosition, setDataPosition] = useState(undefined);
    // Stable portal container attached to document.body.
    const portalContainerRef = useRef(null);
    const getOrCreateContainer = useCallback(() => {
        if (typeof document === "undefined")
            return null;
        if (!portalContainerRef.current) {
            const div = document.createElement("div");
            div.setAttribute("data-seekora-portal", "dropdown");
            document.body.appendChild(div);
            portalContainerRef.current = div;
        }
        return portalContainerRef.current;
    }, []);
    const compute = useCallback(() => {
        if (!anchorRef?.current || typeof window === "undefined") {
            setPortalStyle(undefined);
            setDataPosition(undefined);
            return;
        }
        const rect = anchorRef.current.getBoundingClientRect();
        const vw = window.innerWidth;
        const vh = window.innerHeight;
        let top;
        let position;
        if (rect.bottom + dropdownHeight > vh - 24) {
            // Not enough space below — flip above.
            top = rect.top - dropdownHeight;
            position = "above";
        }
        else {
            top = rect.bottom;
            position = "below";
        }
        // Clamp left so the dropdown does not overflow the right viewport edge.
        const maxLeft = vw - rect.width;
        const left = Math.min(rect.left, maxLeft > 0 ? maxLeft : 0);
        setPortalStyle({
            position: "fixed",
            top: Math.round(top),
            left: Math.round(left),
            width: Math.round(rect.width),
            ...(zIndex !== undefined ? { zIndex } : {}),
        });
        setDataPosition(position);
    }, [anchorRef, dropdownHeight, zIndex]);
    useEffect(() => {
        if (!anchorRef?.current)
            return;
        compute();
        const resizeObserver = new ResizeObserver(compute);
        resizeObserver.observe(anchorRef.current);
        window.addEventListener("scroll", compute, { passive: true });
        window.addEventListener("resize", compute, { passive: true });
        return () => {
            resizeObserver.disconnect();
            window.removeEventListener("scroll", compute);
            window.removeEventListener("resize", compute);
        };
    }, [anchorRef, compute]);
    // Cleanup portal container on unmount.
    useEffect(() => {
        return () => {
            const container = portalContainerRef.current;
            if (container && container.parentNode) {
                container.parentNode.removeChild(container);
            }
            portalContainerRef.current = null;
        };
    }, []);
    const wrapWithPortal = useCallback((node) => {
        if (!anchorRef?.current) {
            // No anchor - fall back to in-flow rendering.
            return node;
        }
        const container = getOrCreateContainer();
        if (!container)
            return node;
        return ReactDOM.createPortal(node, container);
    }, [anchorRef, getOrCreateContainer]);
    return { portalStyle, wrapWithPortal, dataPosition };
}
