"use client";
import {
  usePreviousMouseDownRef
} from "./U3R3WHDK.js";
import {
  isElementMarked
} from "./3NDVDEB4.js";
import {
  isSafariFocusAncestor
} from "./U6HHPQDW.js";
import {
  useStoreState
} from "./Q5W46E73.js";
import {
  useEvent,
  useSafeLayoutEffect
} from "./KPHZR4MB.js";

// src/dialog/utils/use-hide-on-interact-outside.ts
import { contains, getDocument, isVisible } from "@ariakit/core/utils/dom";
import { addGlobalEventListener } from "@ariakit/core/utils/events";
import { useEffect, useRef } from "react";
function isInDocument(target) {
  if (target.tagName === "HTML") return true;
  return contains(getDocument(target).body, target);
}
function isDisclosure(disclosure, target) {
  if (!disclosure) return false;
  if (contains(disclosure, target)) return true;
  const activeId = target.getAttribute("aria-activedescendant");
  if (activeId) {
    const activeElement = getDocument(disclosure).getElementById(activeId);
    if (activeElement) {
      return contains(disclosure, activeElement);
    }
  }
  return false;
}
function isMouseEventOnDialog(event, dialog) {
  if (!("clientY" in event)) return false;
  const rect = dialog.getBoundingClientRect();
  if (rect.width === 0 || rect.height === 0) return false;
  return rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width;
}
function useEventOutside({
  store,
  type,
  listener,
  capture,
  domReady
}) {
  const callListener = useEvent(listener);
  const open = useStoreState(store, "open");
  const focusedRef = useRef(false);
  useSafeLayoutEffect(() => {
    if (!open) return;
    if (!domReady) return;
    const { contentElement } = store.getState();
    if (!contentElement) return;
    const onFocus = () => {
      focusedRef.current = true;
    };
    contentElement.addEventListener("focusin", onFocus, true);
    return () => contentElement.removeEventListener("focusin", onFocus, true);
  }, [store, open, domReady]);
  useEffect(() => {
    if (!open) return;
    const onEvent = (event) => {
      const { contentElement, disclosureElement } = store.getState();
      const target = event.target;
      if (!contentElement) return;
      if (!target) return;
      if (!isInDocument(target)) return;
      if (contains(contentElement, target)) return;
      if (isDisclosure(disclosureElement, target)) return;
      if (target.hasAttribute("data-focus-trap")) return;
      if (isMouseEventOnDialog(event, contentElement)) return;
      const focused = focusedRef.current;
      if (focused && !isElementMarked(target, contentElement.id)) return;
      if (isSafariFocusAncestor(target)) return;
      callListener(event);
    };
    return addGlobalEventListener(type, onEvent, capture);
  }, [open, capture]);
}
function shouldHideOnInteractOutside(hideOnInteractOutside, event) {
  if (typeof hideOnInteractOutside === "function") {
    return hideOnInteractOutside(event);
  }
  return !!hideOnInteractOutside;
}
function useHideOnInteractOutside(store, hideOnInteractOutside, domReady) {
  const open = useStoreState(store, "open");
  const previousMouseDownRef = usePreviousMouseDownRef(open);
  const props = { store, domReady, capture: true };
  useEventOutside({
    ...props,
    type: "click",
    listener: (event) => {
      const { contentElement } = store.getState();
      const previousMouseDown = previousMouseDownRef.current;
      if (!previousMouseDown) return;
      if (!isVisible(previousMouseDown)) return;
      if (!isElementMarked(previousMouseDown, contentElement == null ? void 0 : contentElement.id)) return;
      if (!shouldHideOnInteractOutside(hideOnInteractOutside, event)) return;
      store.hide();
    }
  });
  useEventOutside({
    ...props,
    type: "focusin",
    listener: (event) => {
      const { contentElement } = store.getState();
      if (!contentElement) return;
      if (event.target === getDocument(contentElement)) return;
      if (!shouldHideOnInteractOutside(hideOnInteractOutside, event)) return;
      store.hide();
    }
  });
  useEventOutside({
    ...props,
    type: "contextmenu",
    listener: (event) => {
      if (!shouldHideOnInteractOutside(hideOnInteractOutside, event)) return;
      store.hide();
    }
  });
}

export {
  useHideOnInteractOutside
};
