import * as m from "react";
import { tabbable as Se, isTabbable as Pe, focusable as Ue } from "../../../../../../../tabbable@6.4.0/node_modules/tabbable/dist/index.esm.js";
import { isHTMLElement as H, getNodeName as We, getWindow as $e, getComputedStyle as ze } from "../../../../../../../@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js";
import { useMergedRefs as ye } 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/useMergedRefs.js";
import { useValueAsRef as z } 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/useValueAsRef.js";
import { useStableCallback as J } 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 { useIsoLayoutEffect as Q } 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/useIsoLayoutEffect.js";
import { visuallyHidden as Je } 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/visuallyHidden.js";
import { useTimeout as Fe } 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 { useAnimationFrame as Qe } 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/useAnimationFrame.js";
import { FocusGuard as Te } from "../../utils/FocusGuard.js";
import { createChangeEventDetails as Xe } from "../../utils/createBaseUIEventDetails.js";
import { createAttribute as he } from "../utils/createAttribute.js";
import { enqueueFocus as oe } from "../utils/enqueueFocus.js";
import { markOthers as Ye } from "../utils/markOthers.js";
import { usePortalContext as Ze } from "./FloatingPortal.js";
import { useFloatingTree as Ce } from "./FloatingTree.js";
import { CLICK_TRIGGER_IDENTIFIER as et } from "../../utils/constants.js";
import { resolveRef as w } from "../../utils/resolveRef.js";
import { jsxs as tt, jsx as Ie } from "react/jsx-runtime";
import { isTypeableCombobox as Le, getFloatingFocusElement as ke, getDocument as D, activeElement as _, contains as E, getTarget as X } from "../utils/element.js";
import { getTabbableOptions as ue, isOutsideEvent as Oe, getNextTabbable as nt, getPreviousTabbable as rt } from "../utils/tabbable.js";
import { getNodeAncestors as Ae, getNodeChildren as we } from "../utils/nodes.js";
import { isVirtualClick as ot, isVirtualPointerEvent as st, stopEvent as ut } from "../utils/event.js";
import { triggerHover as it, outsidePress as ct, focusOut as ft } from "../../utils/reason-parts.js";
function at(r, g) {
  const O = $e(r.target);
  return r instanceof O.KeyboardEvent ? "keyboard" : r instanceof O.FocusEvent ? g || "keyboard" : "pointerType" in r ? r.pointerType || "keyboard" : "touches" in r ? "touch" : r instanceof O.MouseEvent ? g || (r.detail === 0 ? "keyboard" : "mouse") : "";
}
const De = 20;
let N = [];
function ie() {
  N = N.filter((r) => r.isConnected);
}
function dt(r) {
  ie(), r && We(r) !== "body" && (N.push(r), N.length > De && (N = N.slice(-De)));
}
function se() {
  return ie(), N[N.length - 1];
}
function lt(r) {
  if (!r)
    return null;
  const g = ue();
  return Pe(r, g) ? r : Se(r, g)[0] || r;
}
function mt(r) {
  return !r || !r.isConnected ? !1 : typeof r.checkVisibility == "function" ? r.checkVisibility() : ze(r).display !== "none";
}
function Ne(r, g) {
  var U;
  if (!g.current.includes("floating") && !((U = r.getAttribute("role")) != null && U.includes("dialog")))
    return;
  const O = ue(), Y = Ue(r, O).filter((S) => {
    const p = S.getAttribute("data-tabindex") || "";
    return Pe(S, O) || S.hasAttribute("data-tabindex") && !p.startsWith("-");
  }), q = r.getAttribute("tabindex");
  g.current.includes("floating") || Y.length === 0 ? q !== "0" && r.setAttribute("tabindex", "0") : (q !== "-1" || r.hasAttribute("data-tabindex") && r.getAttribute("data-tabindex") !== "-1") && (r.setAttribute("tabindex", "-1"), r.setAttribute("data-tabindex", "-1"));
}
function Vt(r) {
  const {
    context: g,
    children: O,
    disabled: f = !1,
    order: Y = ["content"],
    initialFocus: q = !0,
    returnFocus: U = !0,
    restoreFocus: S = !1,
    modal: p = !0,
    closeOnFocusOut: V = !0,
    openInteractionType: xe = "",
    getInsideElements: Me = () => [],
    nextFocusableElement: j,
    previousFocusableElement: B,
    beforeContentFocusGuardRef: Ge,
    externalTree: qe
  } = r, h = "rootStore" in g ? g.rootStore : g, R = h.useState("open"), a = h.useState("domReferenceElement"), d = h.useState("floatingElement"), {
    events: Z,
    dataRef: P
  } = h.context, G = J(() => {
    var t;
    return (t = P.current.floatingContext) == null ? void 0 : t.nodeId;
  }), ce = J(Me), fe = q === !1, I = Le(a) && fe, x = z(Y), ae = z(q), W = z(U), de = z(xe), v = Ce(qe), e = Ze(), Ve = m.useRef(null), je = m.useRef(null), y = m.useRef(!1), $ = m.useRef(!1), C = m.useRef(!1), le = m.useRef(-1), me = m.useRef(""), ee = m.useRef(""), te = m.useRef(null), ne = m.useRef(null), Be = ye(te, Ge, e == null ? void 0 : e.beforeInsideRef), Ke = ye(ne, e == null ? void 0 : e.afterInsideRef), be = Fe(), pe = Fe(), Ee = Qe(), re = e != null, s = ke(d), M = J((t = s) => t ? Se(t, ue()) : []), K = J((t) => {
    const i = M(t);
    return x.current.map(() => i).filter(Boolean).flat();
  });
  m.useEffect(() => {
    if (f || !p)
      return;
    function t(u) {
      u.key === "Tab" && E(s, _(D(s))) && M().length === 0 && !I && ut(u);
    }
    const i = D(s);
    return i.addEventListener("keydown", t), () => {
      i.removeEventListener("keydown", t);
    };
  }, [f, a, s, p, x, I, M, K]), m.useEffect(() => {
    if (f || !d)
      return;
    function t(i) {
      const u = X(i), l = M().indexOf(u);
      l !== -1 && (le.current = l);
    }
    return d.addEventListener("focusin", t), () => {
      d.removeEventListener("focusin", t);
    };
  }, [f, d, M]), m.useEffect(() => {
    if (f || !R)
      return;
    const t = D(s);
    function i() {
      C.current = !1;
    }
    function u(l) {
      const n = X(l), o = E(d, n) || E(a, n) || E(e == null ? void 0 : e.portalNode, n);
      C.current = !o, ee.current = l.pointerType || "keyboard";
    }
    function c() {
      ee.current = "keyboard";
    }
    return t.addEventListener("pointerdown", u, !0), t.addEventListener("pointerup", i, !0), t.addEventListener("pointercancel", i, !0), t.addEventListener("keydown", c, !0), () => {
      t.removeEventListener("pointerdown", u, !0), t.removeEventListener("pointerup", i, !0), t.removeEventListener("pointercancel", i, !0), t.removeEventListener("keydown", c, !0);
    };
  }, [f, d, a, s, R, e]), m.useEffect(() => {
    if (f || !V)
      return;
    function t() {
      $.current = !0, pe.start(0, () => {
        $.current = !1;
      });
    }
    function i(n) {
      const o = n.relatedTarget, L = n.currentTarget, b = X(n);
      queueMicrotask(() => {
        const F = G(), Re = h.context.triggerElements, He = (o == null ? void 0 : o.hasAttribute(he("focus-guard"))) && [te.current, ne.current, e == null ? void 0 : e.beforeInsideRef.current, e == null ? void 0 : e.afterInsideRef.current, e == null ? void 0 : e.beforeOutsideRef.current, e == null ? void 0 : e.afterOutsideRef.current, w(B), w(j)].includes(o), _e = !(E(a, o) || E(d, o) || E(o, d) || E(e == null ? void 0 : e.portalNode, o) || o != null && Re.hasElement(o) || Re.hasMatchingElement((T) => E(T, o)) || He || v && (we(v.nodesRef.current, F).find((T) => {
          var k, A;
          return E((k = T.context) == null ? void 0 : k.elements.floating, o) || E((A = T.context) == null ? void 0 : A.elements.domReference, o);
        }) || Ae(v.nodesRef.current, F).find((T) => {
          var k, A, ve;
          return [(k = T.context) == null ? void 0 : k.elements.floating, ke((A = T.context) == null ? void 0 : A.elements.floating)].includes(o) || ((ve = T.context) == null ? void 0 : ve.elements.domReference) === o;
        })));
        if (L === a && s && Ne(s, x), S && L !== a && !mt(b) && _(D(s)) === D(s).body) {
          if (H(s) && (s.focus(), S === "popup")) {
            Ee.request(() => {
              s.focus();
            });
            return;
          }
          const T = le.current, k = M(), A = k[T] || k[k.length - 1] || s;
          H(A) && A.focus();
        }
        if (P.current.insideReactTree) {
          P.current.insideReactTree = !1;
          return;
        }
        (I || !p) && o && _e && !$.current && // Fix React 18 Strict Mode returnFocus due to double rendering.
        // For an "untrapped" typeable combobox (input role=combobox with
        // initialFocus=false), re-opening the popup and tabbing out should still close it even
        // when the previously focused element (e.g. the next tabbable outside the popup) is
        // focused again. Otherwise, the popup remains open on the second Tab sequence:
        // click input -> Tab (closes) -> click input -> Tab.
        // Allow closing when `isUntrappedTypeableCombobox` regardless of the previously focused element.
        (I || o !== se()) && (y.current = !0, h.setOpen(!1, Xe(ft, n)));
      });
    }
    function u() {
      C.current || (P.current.insideReactTree = !0, be.start(0, () => {
        P.current.insideReactTree = !1;
      }));
    }
    const c = H(a) ? a : null, l = [];
    if (!(!d && !c))
      return c && (c.addEventListener("focusout", i), c.addEventListener("pointerdown", t), l.push(() => {
        c.removeEventListener("focusout", i), c.removeEventListener("pointerdown", t);
      })), d && (d.addEventListener("focusout", i), e && (d.addEventListener("focusout", u, !0), l.push(() => {
        d.removeEventListener("focusout", u, !0);
      })), l.push(() => {
        d.removeEventListener("focusout", i);
      })), () => {
        l.forEach((n) => {
          n();
        });
      };
  }, [f, a, d, s, p, v, e, h, V, S, M, I, G, x, P, be, pe, Ee, j, B]), m.useEffect(() => {
    var n, o, L;
    if (f || !d || !R)
      return;
    const t = Array.from(((n = e == null ? void 0 : e.portalNode) == null ? void 0 : n.querySelectorAll(`[${he("portal")}]`)) || []), u = (L = (o = (v ? Ae(v.nodesRef.current, G()) : []).find((b) => {
      var F;
      return Le(((F = b.context) == null ? void 0 : F.elements.domReference) || null);
    })) == null ? void 0 : o.context) == null ? void 0 : L.elements.domReference, c = [d, u, ...t, ...ce(), Ve.current, je.current, te.current, ne.current, e == null ? void 0 : e.beforeOutsideRef.current, e == null ? void 0 : e.afterOutsideRef.current, w(B), w(j), I ? a : null].filter((b) => b != null), l = Ye(c, p || I);
    return () => {
      l();
    };
  }, [R, f, a, d, p, x, e, I, v, G, ce, j, B]), Q(() => {
    if (!R || f || !H(s))
      return;
    const t = D(s), i = _(t);
    queueMicrotask(() => {
      const u = K(s), c = ae.current, l = typeof c == "function" ? c(de.current || "") : c;
      if (l === void 0 || l === !1)
        return;
      let n;
      l === !0 || l === null ? n = u[0] || s : n = w(l), n = n || u[0] || s, !E(s, i) && oe(n, {
        preventScroll: n === s
      });
    });
  }, [f, R, s, fe, K, ae, de]), Q(() => {
    if (f || !s)
      return;
    const t = D(s), i = _(t);
    dt(i);
    function u(n) {
      if (n.open || (me.current = at(n.nativeEvent, ee.current)), n.reason === it && n.nativeEvent.type === "mouseleave" && (y.current = !0), n.reason === ct)
        if (n.nested)
          y.current = !1;
        else if (ot(n.nativeEvent) || st(n.nativeEvent))
          y.current = !1;
        else {
          let o = !1;
          document.createElement("div").focus({
            get preventScroll() {
              return o = !0, !1;
            }
          }), o ? y.current = !1 : y.current = !0;
        }
    }
    Z.on("openchange", u);
    const c = t.createElement("span");
    c.setAttribute("tabindex", "-1"), c.setAttribute("aria-hidden", "true"), Object.assign(c.style, Je), re && a && a.insertAdjacentElement("afterend", c);
    function l() {
      const n = W.current;
      let o = typeof n == "function" ? n(me.current) : n;
      if (o === void 0 || o === !1)
        return null;
      if (o === null && (o = !0), typeof o == "boolean") {
        const b = a || se();
        return b && b.isConnected ? b : c;
      }
      const L = a || se() || c;
      return w(o) || L;
    }
    return () => {
      Z.off("openchange", u);
      const n = _(t), o = E(d, n) || v && we(v.nodesRef.current, G(), !1).some((b) => {
        var F;
        return E((F = b.context) == null ? void 0 : F.elements.floating, n);
      }), L = l();
      queueMicrotask(() => {
        const b = lt(L), F = typeof W.current != "boolean";
        // eslint-disable-next-line react-hooks/exhaustive-deps
        W.current && !y.current && H(b) && // If the focus moved somewhere else after mount, avoid returning focus
        // since it likely entered a different element which should be
        // respected: https://github.com/floating-ui/floating-ui/issues/2607
        (!(!F && b !== n && n !== t.body) || o) && b.focus({
          preventScroll: !0
        }), c.remove();
      });
    };
  }, [f, d, s, W, P, Z, v, re, a, G]), m.useEffect(() => {
    queueMicrotask(() => {
      y.current = !1;
    });
  }, [f]), m.useEffect(() => {
    if (f || !R)
      return;
    function t(u) {
      const c = X(u);
      c != null && c.closest(`[${et}]`) && ($.current = !0);
    }
    const i = D(s);
    return i.addEventListener("pointerdown", t, !0), () => {
      i.removeEventListener("pointerdown", t, !0);
    };
  }, [f, R, s]), Q(() => {
    if (!f && e)
      return e.setFocusManagerState({
        modal: p,
        closeOnFocusOut: V,
        open: R,
        onOpenChange: h.setOpen,
        domReference: a
      }), () => {
        e.setFocusManagerState(null);
      };
  }, [f, e, p, R, h, V, a]), Q(() => {
    if (!(f || !s))
      return Ne(s, x), () => {
        queueMicrotask(ie);
      };
  }, [f, s, x]);
  const ge = !f && (p ? !I : !0) && (re || p);
  return /* @__PURE__ */ tt(m.Fragment, {
    children: [ge && /* @__PURE__ */ Ie(Te, {
      "data-type": "inside",
      ref: Be,
      onFocus: (t) => {
        var i;
        if (p) {
          const u = K();
          oe(u[u.length - 1]);
        } else if (e != null && e.portalNode)
          if (y.current = !1, Oe(t, e.portalNode)) {
            const u = nt(a);
            u == null || u.focus();
          } else
            (i = w(B ?? e.beforeOutsideRef)) == null || i.focus();
      }
    }), O, ge && /* @__PURE__ */ Ie(Te, {
      "data-type": "inside",
      ref: Ke,
      onFocus: (t) => {
        var i;
        if (p)
          oe(K()[0]);
        else if (e != null && e.portalNode)
          if (V && (y.current = !0), Oe(t, e.portalNode)) {
            const u = rt(a);
            u == null || u.focus();
          } else
            (i = w(j ?? e.afterOutsideRef)) == null || i.focus();
      }
    })]
  });
}
export {
  Vt as FloatingFocusManager
};
