import * as m from "react";
import { isElement as b, isLastTraversableNode as Q, getParentNode as Oe, isHTMLElement as ke, getComputedStyle as De, getOverflowAncestors as Z, isWebKit as Me } from "../../../../../../../@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js";
import { useTimeout as le, Timeout as Ie } from "../../../../../../../@base-ui_utils@0.2.4_@types_react@18.3.27_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/esm/useTimeout.js";
import { useStableCallback as r } from "../../../../../../../@base-ui_utils@0.2.4_@types_react@18.3.27_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/esm/useStableCallback.js";
import { useFloatingTree as Ke } from "../components/FloatingTree.js";
import { createChangeEventDetails as M } from "../../utils/createBaseUIEventDetails.js";
import { createAttribute as xe } from "../utils/createAttribute.js";
import { isReactEvent as Xe } from "../utils/event.js";
import { getTarget as S, getDocument as ae, contains as A, isRootElement as Ye, isEventTargetWithin as d } from "../utils/element.js";
import { getNodeChildren as z } from "../utils/nodes.js";
import { escapeKey as We, outsidePress as _e, triggerPress as fe, none as He } from "../../utils/reason-parts.js";
const Ae = {
  intentional: "onClick",
  sloppy: "onPointerDown"
};
function Be(l) {
  return {
    escapeKey: typeof l == "boolean" ? l : (l == null ? void 0 : l.escapeKey) ?? !1,
    outsidePress: typeof l == "boolean" ? l : (l == null ? void 0 : l.outsidePress) ?? !0
  };
}
function Ze(l, de = {}) {
  const s = "rootStore" in l ? l.rootStore : l, I = s.useState("open"), K = s.useState("floatingElement"), C = s.useState("referenceElement"), B = s.useState("domReferenceElement"), {
    onOpenChange: pe,
    dataRef: E
  } = s.context, {
    enabled: h = !0,
    escapeKey: x = !0,
    outsidePress: X = !0,
    outsidePressEvent: N = "sloppy",
    referencePress: ee = !1,
    referencePressEvent: V = "sloppy",
    ancestorScroll: te = !1,
    bubbles: me,
    externalTree: Ee
  } = de, R = Ke(Ee), he = r(typeof X == "function" ? X : () => !1), L = typeof X == "function" ? he : X, O = m.useRef(!1), {
    escapeKey: Y,
    outsidePress: ne
  } = Be(me), a = m.useRef(null), W = le(), oe = le(), P = r(() => {
    oe.clear(), E.current.insideReactTree = !1;
  }), $ = m.useRef(!1), se = m.useRef(""), q = r((e) => {
    se.current = e.pointerType;
  }), w = r(() => {
    const e = se.current, n = e === "pen" || !e ? "mouse" : e, t = typeof N == "function" ? N() : N;
    return typeof t == "string" ? t : t[n];
  }), g = r((e) => {
    var i;
    if (!I || !h || !x || e.key !== "Escape" || $.current)
      return;
    const n = (i = E.current.floatingContext) == null ? void 0 : i.nodeId, t = R ? z(R.nodesRef.current, n) : [];
    if (!Y && t.length > 0) {
      let c = !0;
      if (t.forEach((y) => {
        var H;
        (H = y.context) != null && H.open && !y.context.dataRef.current.__escapeKeyBubbles && (c = !1);
      }), !c)
        return;
    }
    const f = Xe(e) ? e.nativeEvent : e, o = M(We, f);
    s.setOpen(!1, o), !Y && !o.isPropagationAllowed && e.stopPropagation();
  }), ye = r((e) => {
    const n = w();
    return n === "intentional" && e.type !== "click" || n === "sloppy" && e.type === "click";
  }), T = r(() => {
    E.current.insideReactTree = !0, oe.start(0, P);
  }), k = r((e, n = !1) => {
    var ue;
    if (ye(e)) {
      P();
      return;
    }
    if (E.current.insideReactTree) {
      P();
      return;
    }
    if (w() === "intentional" && n || typeof L == "function" && !L(e))
      return;
    const t = S(e), f = `[${xe("inert")}]`, o = ae(s.select("floatingElement")).querySelectorAll(f), i = s.context.triggerElements;
    if (t && (i.hasElement(t) || i.hasMatchingElement((u) => A(u, t))))
      return;
    let c = b(t) ? t : null;
    for (; c && !Q(c); ) {
      const u = Oe(c);
      if (Q(u) || !b(u))
        break;
      c = u;
    }
    if (o.length && b(t) && !Ye(t) && // Clicked on a direct ancestor (e.g. FloatingOverlay).
    !A(t, s.select("floatingElement")) && // If the target root element contains none of the markers, then the
    // element was injected after the floating element rendered.
    Array.from(o).every((u) => !A(c, u)))
      return;
    if (ke(t) && !("touches" in e)) {
      const u = Q(t), p = De(t), D = /auto|scroll/, Re = u || D.test(p.overflowX), Le = u || D.test(p.overflowY), Pe = Re && t.clientWidth > 0 && t.scrollWidth > t.clientWidth, we = Le && t.clientHeight > 0 && t.scrollHeight > t.clientHeight, be = p.direction === "rtl", Se = we && (be ? e.offsetX <= t.offsetWidth - t.clientWidth : e.offsetX > t.clientWidth), Ce = Pe && e.offsetY > t.clientHeight;
      if (Se || Ce)
        return;
    }
    const y = (ue = E.current.floatingContext) == null ? void 0 : ue.nodeId, H = R && z(R.nodesRef.current, y).some((u) => {
      var p;
      return d(e, (p = u.context) == null ? void 0 : p.elements.floating);
    });
    if (d(e, s.select("floatingElement")) || d(e, s.select("domReferenceElement")) || H)
      return;
    const ie = R ? z(R.nodesRef.current, y) : [];
    if (ie.length > 0) {
      let u = !0;
      if (ie.forEach((p) => {
        var D;
        (D = p.context) != null && D.open && !p.context.dataRef.current.__outsidePressBubbles && (u = !1);
      }), !u)
        return;
    }
    s.setOpen(!1, M(_e, e)), P();
  }), re = r((e) => {
    w() !== "sloppy" || e.pointerType === "touch" || !s.select("open") || !h || d(e, s.select("floatingElement")) || d(e, s.select("domReferenceElement")) || k(e);
  }), ge = r((e) => {
    if (w() !== "sloppy" || !s.select("open") || !h || d(e, s.select("floatingElement")) || d(e, s.select("domReferenceElement")))
      return;
    const n = e.touches[0];
    n && (a.current = {
      startTime: Date.now(),
      startX: n.clientX,
      startY: n.clientY,
      dismissOnTouchEnd: !1,
      dismissOnMouseDown: !0
    }, W.start(1e3, () => {
      a.current && (a.current.dismissOnTouchEnd = !1, a.current.dismissOnMouseDown = !1);
    }));
  }), F = r((e) => {
    const n = S(e);
    function t() {
      ge(e), n == null || n.removeEventListener(e.type, t);
    }
    n == null || n.addEventListener(e.type, t);
  }), v = r((e) => {
    const n = O.current;
    if (O.current = !1, W.clear(), e.type === "mousedown" && a.current && !a.current.dismissOnMouseDown)
      return;
    const t = S(e);
    function f() {
      e.type === "pointerdown" ? re(e) : k(e, n), t == null || t.removeEventListener(e.type, f);
    }
    t == null || t.addEventListener(e.type, f);
  }), Te = r((e) => {
    if (w() !== "sloppy" || !a.current || d(e, s.select("floatingElement")) || d(e, s.select("domReferenceElement")))
      return;
    const n = e.touches[0];
    if (!n)
      return;
    const t = Math.abs(n.clientX - a.current.startX), f = Math.abs(n.clientY - a.current.startY), o = Math.sqrt(t * t + f * f);
    o > 5 && (a.current.dismissOnTouchEnd = !0), o > 10 && (k(e), W.clear(), a.current = null);
  }), U = r((e) => {
    const n = S(e);
    function t() {
      Te(e), n == null || n.removeEventListener(e.type, t);
    }
    n == null || n.addEventListener(e.type, t);
  }), ve = r((e) => {
    w() !== "sloppy" || !a.current || d(e, s.select("floatingElement")) || d(e, s.select("domReferenceElement")) || (a.current.dismissOnTouchEnd && k(e), W.clear(), a.current = null);
  }), j = r((e) => {
    const n = S(e);
    function t() {
      ve(e), n == null || n.removeEventListener(e.type, t);
    }
    n == null || n.addEventListener(e.type, t);
  });
  m.useEffect(() => {
    if (!I || !h)
      return;
    E.current.__escapeKeyBubbles = Y, E.current.__outsidePressBubbles = ne;
    const e = new Ie();
    function n(c) {
      s.setOpen(!1, M(He, c));
    }
    function t() {
      e.clear(), $.current = !0;
    }
    function f() {
      e.start(
        // 0ms or 1ms don't work in Safari. 5ms appears to consistently work.
        // Only apply to WebKit for the test to remain 0ms.
        Me() ? 5 : 0,
        () => {
          $.current = !1;
        }
      );
    }
    const o = ae(K);
    o.addEventListener("pointerdown", q, !0), x && (o.addEventListener("keydown", g), o.addEventListener("compositionstart", t), o.addEventListener("compositionend", f)), L && (o.addEventListener("click", v, !0), o.addEventListener("pointerdown", v, !0), o.addEventListener("touchstart", F, !0), o.addEventListener("touchmove", U, !0), o.addEventListener("touchend", j, !0), o.addEventListener("mousedown", v, !0));
    let i = [];
    return te && (b(B) && (i = Z(B)), b(K) && (i = i.concat(Z(K))), !b(C) && C && C.contextElement && (i = i.concat(Z(C.contextElement)))), i = i.filter((c) => {
      var y;
      return c !== ((y = o.defaultView) == null ? void 0 : y.visualViewport);
    }), i.forEach((c) => {
      c.addEventListener("scroll", n, {
        passive: !0
      });
    }), () => {
      o.removeEventListener("pointerdown", q, !0), x && (o.removeEventListener("keydown", g), o.removeEventListener("compositionstart", t), o.removeEventListener("compositionend", f)), L && (o.removeEventListener("click", v, !0), o.removeEventListener("pointerdown", v, !0), o.removeEventListener("touchstart", F, !0), o.removeEventListener("touchmove", U, !0), o.removeEventListener("touchend", j, !0), o.removeEventListener("mousedown", v, !0)), i.forEach((c) => {
        c.removeEventListener("scroll", n);
      }), e.clear(), O.current = !1;
    };
  }, [E, K, C, B, x, L, I, pe, te, h, Y, ne, g, k, v, re, F, U, j, q, s]), m.useEffect(P, [L, P]);
  const G = m.useMemo(() => ({
    onKeyDown: g,
    ...ee && {
      [Ae[V]]: (e) => {
        s.setOpen(!1, M(fe, e.nativeEvent));
      },
      ...V !== "intentional" && {
        onClick(e) {
          s.setOpen(!1, M(fe, e.nativeEvent));
        }
      }
    }
  }), [g, s, ee, V]), _ = r((e) => {
    const n = S(e.nativeEvent);
    !A(s.select("floatingElement"), n) || e.button !== 0 || (O.current = !0);
  }), J = r((e) => {
    !I || !h || e.button !== 0 || (O.current = !0);
  }), ce = m.useMemo(() => ({
    onKeyDown: g,
    // `onMouseDown` may be blocked if `event.preventDefault()` is called in
    // `onPointerDown`, such as with <NumberField.ScrubArea>.
    // See https://github.com/mui/base-ui/pull/3379
    onPointerDown: _,
    onMouseDown: _,
    onMouseUp: _,
    onClickCapture: T,
    onMouseDownCapture(e) {
      T(), J(e);
    },
    onPointerDownCapture(e) {
      T(), J(e);
    },
    onMouseUpCapture: T,
    onTouchEndCapture: T,
    onTouchMoveCapture: T
  }), [g, _, T, J]);
  return m.useMemo(() => h ? {
    reference: G,
    floating: ce,
    trigger: G
  } : {}, [h, G, ce]);
}
export {
  Be as normalizeProp,
  Ze as useDismiss
};
