import * as p from "react";
import { isHTMLElement as be } from "../../../../../../../@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js";
import { useValueAsRef as N } 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 ae } 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 k } 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 { useFloatingParentNodeId as ze, useFloatingTree as Ge } from "../components/FloatingTree.js";
import { createChangeEventDetails as Y } from "../../utils/createBaseUIEventDetails.js";
import { enqueueFocus as We } from "../utils/enqueueFocus.js";
import { ARROW_DOWN as re, ARROW_LEFT as _, ARROW_RIGHT as q, ARROW_UP as Te } from "../utils/constants.js";
import { getFloatingFocusElement as _e, isTypeableCombobox as qe, activeElement as Me, getDocument as He, contains as Pe, getTarget as $e } from "../utils/element.js";
import { isIndexOutOfListBounds as ve, getMinListIndex as fe, getMaxListIndex as Ce, createGridCellMap as Be, isListIndexDisabled as de, getGridNavigatedIndex as Ue, getGridCellIndexOfCorner as je, getGridCellIndices as Je, findNonDisabledListIndex as Z } from "../utils/composite.js";
import { stopEvent as S, isVirtualClick as Qe, isVirtualPointerEvent as Xe } from "../utils/event.js";
import { listNavigation as me, focusOut as Ye } from "../../utils/reason-parts.js";
const Ze = "Escape";
function te(i, g, u) {
  switch (i) {
    case "vertical":
      return g;
    case "horizontal":
      return u;
    default:
      return g || u;
  }
}
function ee(i, g) {
  return te(g, i === Te || i === re, i === _ || i === q);
}
function pe(i, g, u) {
  return te(g, i === re, u ? i === _ : i === q) || i === "Enter" || i === " " || i === "";
}
function er(i, g, u) {
  return te(g, u ? i === _ : i === q, i === re);
}
function rr(i, g, u, l) {
  const I = u ? i === q : i === _, E = i === Te;
  return g === "both" || g === "horizontal" && l && l > 1 ? i === Ze : te(g, I, E);
}
function pr(i, g) {
  const u = "rootStore" in i ? i.rootStore : i, l = u.useState("open"), I = u.useState("floatingElement"), E = u.useState("domReferenceElement"), ge = u.context.dataRef, {
    listRef: o,
    activeIndex: M,
    onNavigate: Se = () => {
    },
    enabled: w = !0,
    selectedIndex: D = null,
    allowEscape: ne = !1,
    loopFocus: H = !1,
    nested: P = !1,
    rtl: y = !1,
    virtual: f = !1,
    focusItemOnOpen: v = "auto",
    focusItemOnHover: oe = !0,
    openOnArrowKeyDown: ie = !0,
    disabledIndices: h = void 0,
    orientation: d = "vertical",
    parentOrientation: Ie,
    cols: F = 1,
    scrollItemIntoView: Fe = !0,
    itemSizes: Ae,
    dense: Le = !1,
    id: Re,
    resetOnPointerLeave: Ne = !0,
    externalTree: ke
  } = g;
  process.env.NODE_ENV !== "production" && (ne && (H || console.warn("`useListNavigation` looping must be enabled to allow escaping."), f || console.warn("`useListNavigation` must be virtual to allow escaping.")), d === "vertical" && F > 1 && console.warn("In grid list navigation mode (`cols` > 1), the `orientation` should", 'be either "horizontal" or "both".'));
  const De = _e(I), K = N(De), $ = ze(), R = Ge(ke);
  k(() => {
    ge.current.orientation = d;
  }, [ge, d]);
  const ce = qe(E), C = p.useRef(v), t = p.useRef(D ?? -1), T = p.useRef(null), A = p.useRef(!0), a = ae((e) => {
    Se(t.current === -1 ? null : t.current, e);
  }), he = p.useRef(a), V = p.useRef(!!I), Oe = p.useRef(l), O = p.useRef(!1), B = p.useRef(!1), ue = N(h), U = N(l), Ke = N(Fe), z = N(D), xe = N(Ne), se = ae(() => {
    function e(s) {
      f ? R == null || R.events.emit("virtualfocus", s) : We(s, {
        sync: O.current,
        preventScroll: !0
      });
    }
    const n = o.current[t.current], r = B.current;
    n && e(n), (O.current ? (s) => s() : requestAnimationFrame)(() => {
      var L;
      const s = o.current[t.current] || n;
      if (!s)
        return;
      n || e(s);
      const m = Ke.current;
      m && // eslint-disable-next-line @typescript-eslint/no-use-before-define
      le && (r || !A.current) && ((L = s.scrollIntoView) == null || L.call(s, typeof m == "boolean" ? {
        block: "nearest",
        inline: "nearest"
      } : m));
    });
  });
  k(() => {
    w && (l && I ? (t.current = D ?? -1, C.current && D != null && (B.current = !0, a())) : V.current && (t.current = -1, he.current()));
  }, [w, l, I, D, a]), k(() => {
    if (w) {
      if (!l) {
        O.current = !1;
        return;
      }
      if (I)
        if (M == null) {
          if (O.current = !1, z.current != null)
            return;
          if (V.current && (t.current = -1, se()), (!Oe.current || !V.current) && C.current && (T.current != null || C.current === !0 && T.current == null)) {
            let e = 0;
            const n = () => {
              o.current[0] == null ? (e < 2 && (e ? requestAnimationFrame : queueMicrotask)(n), e += 1) : (t.current = T.current == null || pe(T.current, d, y) || P ? fe(o) : Ce(o), T.current = null, a());
            };
            n();
          }
        } else ve(o, M) || (t.current = M, se(), B.current = !1);
    }
  }, [w, l, I, M, z, P, o, d, y, a, se, ue]), k(() => {
    var s, m;
    if (!w || I || !R || f || !V.current)
      return;
    const e = R.nodesRef.current, n = (m = (s = e.find((x) => x.id === $)) == null ? void 0 : s.context) == null ? void 0 : m.elements.floating, r = Me(He(I)), c = e.some((x) => x.context && Pe(x.context.elements.floating, r));
    n && !c && A.current && n.focus({
      preventScroll: !0
    });
  }, [w, I, R, $, f]), k(() => {
    he.current = a, Oe.current = l, V.current = !!I;
  }), k(() => {
    l || (T.current = null, C.current = v);
  }, [l, v]);
  const Ee = M != null, le = p.useMemo(() => {
    function e(r) {
      if (!U.current)
        return;
      const c = o.current.indexOf(r.currentTarget);
      c !== -1 && t.current !== c && (t.current = c, a(r));
    }
    return {
      onFocus(r) {
        O.current = !0, e(r);
      },
      onClick: ({
        currentTarget: r
      }) => r.focus({
        preventScroll: !0
      }),
      // Safari
      onMouseMove(r) {
        O.current = !0, B.current = !1, oe && e(r);
      },
      onPointerLeave(r) {
        var s;
        if (!U.current || !A.current || r.pointerType === "touch")
          return;
        O.current = !0;
        const c = r.relatedTarget;
        !oe || o.current.includes(c) || xe.current && (t.current = -1, a(r), f || (s = K.current) == null || s.focus({
          preventScroll: !0
        }));
      }
    };
  }, [U, K, oe, o, a, xe, f]), j = p.useCallback(() => {
    var e, n, r;
    return Ie ?? ((r = (n = (e = R == null ? void 0 : R.nodesRef.current.find((c) => c.id === $)) == null ? void 0 : e.context) == null ? void 0 : n.dataRef) == null ? void 0 : r.current.orientation);
  }, [$, R, Ie]), G = ae((e) => {
    if (A.current = !1, O.current = !0, e.which === 229 || !U.current && e.currentTarget === K.current)
      return;
    if (P && rr(e.key, d, y, F)) {
      ee(e.key, j()) || S(e), u.setOpen(!1, Y(me, e.nativeEvent)), be(E) && (f ? R == null || R.events.emit("virtualfocus", E) : E.focus());
      return;
    }
    const n = t.current, r = fe(o, h), c = Ce(o, h);
    if (ce || (e.key === "Home" && (S(e), t.current = r, a(e)), e.key === "End" && (S(e), t.current = c, a(e))), F > 1) {
      const s = Ae || Array.from({
        length: o.current.length
      }, () => ({
        width: 1,
        height: 1
      })), m = Be(s, F, Le), x = m.findIndex((b) => b != null && !de(o, b, h)), L = m.reduce((b, W, Ve) => W != null && !de(o, W, h) ? Ve : b, -1), X = m[Ue({
        current: m.map((b) => b != null ? o.current[b] : null)
      }, {
        event: e,
        orientation: d,
        loopFocus: H,
        rtl: y,
        cols: F,
        // treat undefined (empty grid spaces) as disabled indices so we
        // don't end up in them
        disabledIndices: Je([...(typeof h != "function" ? h : null) || o.current.map((b, W) => de(o, W, h) ? W : void 0), void 0], m),
        minIndex: x,
        maxIndex: L,
        prevIndex: je(
          t.current > c ? r : t.current,
          s,
          m,
          F,
          // use a corner matching the edge closest to the direction
          // we're moving in so we don't end up in the same item. Prefer
          // top/left over bottom/right.
          // eslint-disable-next-line no-nested-ternary
          e.key === re ? "bl" : e.key === (y ? _ : q) ? "tr" : "tl"
        ),
        stopEvent: !0
      })];
      if (X != null && (t.current = X, a(e)), d === "both")
        return;
    }
    if (ee(e.key, d)) {
      if (S(e), l && !f && Me(e.currentTarget.ownerDocument) === e.currentTarget) {
        t.current = pe(e.key, d, y) ? r : c, a(e);
        return;
      }
      pe(e.key, d, y) ? H ? n >= c ? ne && n !== o.current.length ? t.current = -1 : (O.current = !1, t.current = r) : t.current = Z(o, {
        startingIndex: n,
        disabledIndices: h
      }) : t.current = Math.min(c, Z(o, {
        startingIndex: n,
        disabledIndices: h
      })) : H ? n <= r ? ne && n !== -1 ? t.current = o.current.length : (O.current = !1, t.current = c) : t.current = Z(o, {
        startingIndex: n,
        decrement: !0,
        disabledIndices: h
      }) : t.current = Math.max(r, Z(o, {
        startingIndex: n,
        decrement: !0,
        disabledIndices: h
      })), ve(o, t.current) && (t.current = -1), a(e);
    }
  }), J = p.useMemo(() => f && l && Ee && {
    "aria-activedescendant": `${Re}-${M}`
  }, [f, l, Ee, Re, M]), ye = p.useMemo(() => ({
    "aria-orientation": d === "both" ? void 0 : d,
    ...ce ? {} : J,
    onKeyDown(e) {
      if (e.key === "Tab" && e.shiftKey && l && !f) {
        const n = $e(e.nativeEvent);
        if (n && !Pe(K.current, n))
          return;
        S(e), u.setOpen(!1, Y(Ye, e.nativeEvent)), be(E) && E.focus();
        return;
      }
      G(e);
    },
    onPointerMove() {
      A.current = !0;
    }
  }), [J, G, K, d, ce, u, l, f, E]), Q = p.useMemo(() => {
    function e(r) {
      v === "auto" && Qe(r.nativeEvent) && (C.current = !f);
    }
    function n(r) {
      C.current = v, v === "auto" && Xe(r.nativeEvent) && (C.current = !0);
    }
    return {
      onKeyDown(r) {
        const c = u.select("open");
        A.current = !1;
        const s = r.key.startsWith("Arrow"), m = er(r.key, j(), y), x = ee(r.key, d), L = (P ? m : x) || r.key === "Enter" || r.key.trim() === "";
        if (f && c)
          return G(r);
        if (!(!c && !ie && s)) {
          if (L) {
            const X = ee(r.key, j());
            T.current = P && X ? null : r.key;
          }
          if (P) {
            m && (S(r), c ? (t.current = fe(o, ue.current), a(r)) : u.setOpen(!0, Y(me, r.nativeEvent, r.currentTarget)));
            return;
          }
          x && (z.current != null && (t.current = z.current), S(r), !c && ie ? u.setOpen(!0, Y(me, r.nativeEvent, r.currentTarget)) : G(r), c && a(r));
        }
      },
      onFocus(r) {
        u.select("open") && !f && (t.current = -1, a(r));
      },
      onPointerDown: n,
      onPointerEnter: n,
      onMouseDown: e,
      onClick: e
    };
  }, [G, ue, v, o, P, a, u, ie, d, j, y, z, f]), we = p.useMemo(() => ({
    ...J,
    ...Q
  }), [J, Q]);
  return p.useMemo(() => w ? {
    reference: we,
    floating: ye,
    item: le,
    trigger: Q
  } : {}, [w, we, ye, Q, le]);
}
export {
  Ze as ESCAPE,
  pr as useListNavigation
};
