"use client";
import { getEventPoint, getElementPolygon, isPointInPolygon } from './X7QOZUD3.js';
import { useHovercardProviderContext, HovercardScopedContextProvider } from './EM5CXX6A.js';
import { usePopover } from './G7GW6PWC.js';
import { createDialogComponent } from './DVTPF4J4.js';
import { createHook, forwardRef as forwardRef2, createElement } from './LMDWO4NN.js';
import { usePortalRef, useIsMouseMoving, useBooleanEvent, useLiveRef, useSafeLayoutEffect, useWrapElement, useMergeRefs, useEvent } from './ABQUS43J.js';
import { __objRest, __spreadProps, __spreadValues } from './3YLGPPWQ.js';
import { contains } from '../../../../../../@ariakit_core@0.4.15/node_modules/@ariakit/core/esm/__chunks/DTR5TSDJ.js';
import { addGlobalEventListener } from '../../../../../../@ariakit_core@0.4.15/node_modules/@ariakit/core/esm/utils/events.js';
import { hasFocusWithin } from '../../../../../../@ariakit_core@0.4.15/node_modules/@ariakit/core/esm/utils/focus.js';
import { invariant, chain, isFalsyBooleanCallback } from '../../../../../../@ariakit_core@0.4.15/node_modules/@ariakit/core/esm/__chunks/PBFD2E7P.js';
import { sync } from '../../../../../../@ariakit_core@0.4.15/node_modules/@ariakit/core/esm/__chunks/BCALMBPZ.js';
import { createContext, useRef, useState, useEffect, useContext, useCallback } from 'react';
import { jsx } from 'react/jsx-runtime';

var TagName = "div";
function isMovingOnHovercard(target, card, anchor, nested) {
  if (hasFocusWithin(card)) return true;
  if (!target) return false;
  if (contains(card, target)) return true;
  if (anchor && contains(anchor, target)) return true;
  if (nested == null ? void 0 : nested.some((card2) => isMovingOnHovercard(target, card2, anchor))) {
    return true;
  }
  return false;
}
function useAutoFocusOnHide(_a) {
  var _b = _a, {
    store
  } = _b, props = __objRest(_b, [
    "store"
  ]);
  const [autoFocusOnHide, setAutoFocusOnHide] = useState(false);
  const mounted = store.useState("mounted");
  useEffect(() => {
    if (!mounted) {
      setAutoFocusOnHide(false);
    }
  }, [mounted]);
  const onFocusProp = props.onFocus;
  const onFocus = useEvent((event) => {
    onFocusProp == null ? void 0 : onFocusProp(event);
    if (event.defaultPrevented) return;
    setAutoFocusOnHide(true);
  });
  const finalFocusRef = useRef(null);
  useEffect(() => {
    return sync(store, ["anchorElement"], (state) => {
      finalFocusRef.current = state.anchorElement;
    });
  }, []);
  props = __spreadProps(__spreadValues({
    autoFocusOnHide,
    finalFocus: finalFocusRef
  }, props), {
    onFocus
  });
  return props;
}
var NestedHovercardContext = createContext(null);
var useHovercard = createHook(
  function useHovercard2(_a) {
    var _b = _a, {
      store,
      modal = false,
      portal = !!modal,
      hideOnEscape = true,
      hideOnHoverOutside = true,
      disablePointerEventsOnApproach = !!hideOnHoverOutside
    } = _b, props = __objRest(_b, [
      "store",
      "modal",
      "portal",
      "hideOnEscape",
      "hideOnHoverOutside",
      "disablePointerEventsOnApproach"
    ]);
    const context = useHovercardProviderContext();
    store = store || context;
    invariant(
      store,
      process.env.NODE_ENV !== "production" && "Hovercard must receive a `store` prop or be wrapped in a HovercardProvider component."
    );
    const ref = useRef(null);
    const [nestedHovercards, setNestedHovercards] = useState([]);
    const hideTimeoutRef = useRef(0);
    const enterPointRef = useRef(null);
    const { portalRef, domReady } = usePortalRef(portal, props.portalRef);
    const isMouseMoving = useIsMouseMoving();
    const mayHideOnHoverOutside = !!hideOnHoverOutside;
    const hideOnHoverOutsideProp = useBooleanEvent(hideOnHoverOutside);
    const mayDisablePointerEvents = !!disablePointerEventsOnApproach;
    const disablePointerEventsProp = useBooleanEvent(
      disablePointerEventsOnApproach
    );
    const open = store.useState("open");
    const mounted = store.useState("mounted");
    useEffect(() => {
      if (!domReady) return;
      if (!mounted) return;
      if (!mayHideOnHoverOutside && !mayDisablePointerEvents) return;
      const element = ref.current;
      if (!element) return;
      const onMouseMove = (event) => {
        if (!store) return;
        if (!isMouseMoving()) return;
        const { anchorElement, hideTimeout, timeout } = store.getState();
        const enterPoint = enterPointRef.current;
        const [target] = event.composedPath();
        const anchor = anchorElement;
        if (isMovingOnHovercard(target, element, anchor, nestedHovercards)) {
          enterPointRef.current = target && anchor && contains(anchor, target) ? getEventPoint(event) : null;
          window.clearTimeout(hideTimeoutRef.current);
          hideTimeoutRef.current = 0;
          return;
        }
        if (hideTimeoutRef.current) return;
        if (enterPoint) {
          const currentPoint = getEventPoint(event);
          const polygon = getElementPolygon(element, enterPoint);
          if (isPointInPolygon(currentPoint, polygon)) {
            enterPointRef.current = currentPoint;
            if (!disablePointerEventsProp(event)) return;
            event.preventDefault();
            event.stopPropagation();
            return;
          }
        }
        if (!hideOnHoverOutsideProp(event)) return;
        hideTimeoutRef.current = window.setTimeout(() => {
          hideTimeoutRef.current = 0;
          store == null ? void 0 : store.hide();
        }, hideTimeout != null ? hideTimeout : timeout);
      };
      return chain(
        addGlobalEventListener("mousemove", onMouseMove, true),
        () => clearTimeout(hideTimeoutRef.current)
      );
    }, [
      store,
      isMouseMoving,
      domReady,
      mounted,
      mayHideOnHoverOutside,
      mayDisablePointerEvents,
      nestedHovercards,
      disablePointerEventsProp,
      hideOnHoverOutsideProp
    ]);
    useEffect(() => {
      if (!domReady) return;
      if (!mounted) return;
      if (!mayDisablePointerEvents) return;
      const disableEvent = (event) => {
        const element = ref.current;
        if (!element) return;
        const enterPoint = enterPointRef.current;
        if (!enterPoint) return;
        const polygon = getElementPolygon(element, enterPoint);
        if (isPointInPolygon(getEventPoint(event), polygon)) {
          if (!disablePointerEventsProp(event)) return;
          event.preventDefault();
          event.stopPropagation();
        }
      };
      return chain(
        // Note: we may need to add pointer events here in the future.
        addGlobalEventListener("mouseenter", disableEvent, true),
        addGlobalEventListener("mouseover", disableEvent, true),
        addGlobalEventListener("mouseout", disableEvent, true),
        addGlobalEventListener("mouseleave", disableEvent, true)
      );
    }, [domReady, mounted, mayDisablePointerEvents, disablePointerEventsProp]);
    useEffect(() => {
      if (!domReady) return;
      if (open) return;
      store == null ? void 0 : store.setAutoFocusOnShow(false);
    }, [store, domReady, open]);
    const openRef = useLiveRef(open);
    useEffect(() => {
      if (!domReady) return;
      return () => {
        if (!openRef.current) {
          store == null ? void 0 : store.setAutoFocusOnShow(false);
        }
      };
    }, [store, domReady]);
    const registerOnParent = useContext(NestedHovercardContext);
    useSafeLayoutEffect(() => {
      if (modal) return;
      if (!portal) return;
      if (!mounted) return;
      if (!domReady) return;
      const element = ref.current;
      if (!element) return;
      return registerOnParent == null ? void 0 : registerOnParent(element);
    }, [modal, portal, mounted, domReady]);
    const registerNestedHovercard = useCallback(
      (element) => {
        setNestedHovercards((prevElements) => [...prevElements, element]);
        const parentUnregister = registerOnParent == null ? void 0 : registerOnParent(element);
        return () => {
          setNestedHovercards(
            (prevElements) => prevElements.filter((item) => item !== element)
          );
          parentUnregister == null ? void 0 : parentUnregister();
        };
      },
      [registerOnParent]
    );
    props = useWrapElement(
      props,
      (element) => /* @__PURE__ */ jsx(HovercardScopedContextProvider, { value: store, children: /* @__PURE__ */ jsx(NestedHovercardContext.Provider, { value: registerNestedHovercard, children: element }) }),
      [store, registerNestedHovercard]
    );
    props = __spreadProps(__spreadValues({}, props), {
      ref: useMergeRefs(ref, props.ref)
    });
    props = useAutoFocusOnHide(__spreadValues({ store }, props));
    const autoFocusOnShow = store.useState(
      (state) => modal || state.autoFocusOnShow
    );
    props = usePopover(__spreadProps(__spreadValues({
      store,
      modal,
      portal,
      autoFocusOnShow
    }, props), {
      portalRef,
      hideOnEscape(event) {
        if (isFalsyBooleanCallback(hideOnEscape, event)) return false;
        requestAnimationFrame(() => {
          requestAnimationFrame(() => {
            store == null ? void 0 : store.hide();
          });
        });
        return true;
      }
    }));
    return props;
  }
);
createDialogComponent(
  forwardRef2(function Hovercard2(props) {
    const htmlProps = useHovercard(props);
    return createElement(TagName, htmlProps);
  }),
  useHovercardProviderContext
);

export { useHovercard };
//# sourceMappingURL=ZFX5QU3H.js.map
