import E, { useRef as w } from "react";
import { useDisposables as C } from "../../hooks/use-disposables.js";
import { useEvent as A } from "../../hooks/use-event.js";
import { useEventListener as K } from "../../hooks/use-event-listener.js";
import { useIsMounted as I } from "../../hooks/use-is-mounted.js";
import { useIsTopLayer as M } from "../../hooks/use-is-top-layer.js";
import { useOnUnmount as U } from "../../hooks/use-on-unmount.js";
import { useOwnerDocument as _ } from "../../hooks/use-owner.js";
import { useServerHandoffComplete as j } from "../../hooks/use-server-handoff-complete.js";
import { useSyncRefs as q } from "../../hooks/use-sync-refs.js";
import { useTabDirection as G, Direction as T } from "../../hooks/use-tab-direction.js";
import { useWatch as g } from "../../hooks/use-watch.js";
import { Hidden as h, HiddenFeatures as $ } from "../../internal/hidden.js";
import { history as k } from "../../utils/active-element-history.js";
import { focusIn as v, Focus as f, focusElement as l, FocusResult as H } from "../../utils/focus-management.js";
import { match as R } from "../../utils/match.js";
import { microTask as P } from "../../utils/micro-task.js";
import { forwardRefWithAs as V, useRender as Z } from "../../utils/render.js";
function S(e) {
  if (!e) return /* @__PURE__ */ new Set();
  if (typeof e == "function") return new Set(e());
  let r = /* @__PURE__ */ new Set();
  for (let t of e.current) t.current instanceof HTMLElement && r.add(t.current);
  return r;
}
let z = "div";
var x = ((e) => (e[e.None = 0] = "None", e[e.InitialFocus = 1] = "InitialFocus", e[e.TabLock = 2] = "TabLock", e[e.FocusLock = 4] = "FocusLock", e[e.RestoreFocus = 8] = "RestoreFocus", e[e.AutoFocus = 16] = "AutoFocus", e))(x || {});
function J(e, r) {
  let t = w(null), n = q(t, r), { initialFocus: u, initialFocusFallback: s, containers: m, features: o = 15, ...i } = e;
  j() || (o = 0);
  let a = _(t);
  Y(o, { ownerDocument: a });
  let d = ee(o, { ownerDocument: a, container: t, initialFocus: u, initialFocusFallback: s });
  te(o, { ownerDocument: a, container: t, containers: m, previousActiveElement: d });
  let L = G(), D = A((c) => {
    let p = t.current;
    p && ((F) => F())(() => {
      R(L.current, { [T.Forwards]: () => {
        v(p, f.First, { skipElements: [c.relatedTarget, s] });
      }, [T.Backwards]: () => {
        v(p, f.Last, { skipElements: [c.relatedTarget, s] });
      } });
    });
  }), y = M(!!(o & 2), "focus-trap#tab-lock"), N = C(), b = w(!1), O = { ref: n, onKeyDown(c) {
    c.key == "Tab" && (b.current = !0, N.requestAnimationFrame(() => {
      b.current = !1;
    }));
  }, onBlur(c) {
    if (!(o & 4)) return;
    let p = S(m);
    t.current instanceof HTMLElement && p.add(t.current);
    let F = c.relatedTarget;
    F instanceof HTMLElement && F.dataset.headlessuiFocusGuard !== "true" && (B(p, F) || (b.current ? v(t.current, R(L.current, { [T.Forwards]: () => f.Next, [T.Backwards]: () => f.Previous }) | f.WrapAround, { relativeTo: c.target }) : c.target instanceof HTMLElement && l(c.target)));
  } }, W = Z();
  return E.createElement(E.Fragment, null, y && E.createElement(h, { as: "button", type: "button", "data-headlessui-focus-guard": !0, onFocus: D, features: $.Focusable }), W({ ourProps: O, theirProps: i, defaultTag: z, name: "FocusTrap" }), y && E.createElement(h, { as: "button", type: "button", "data-headlessui-focus-guard": !0, onFocus: D, features: $.Focusable }));
}
let Q = V(J), be = Object.assign(Q, { features: x });
function X(e = !0) {
  let r = w(k.slice());
  return g(([t], [n]) => {
    n === !0 && t === !1 && P(() => {
      r.current.splice(0);
    }), n === !1 && t === !0 && (r.current = k.slice());
  }, [e, k, r]), A(() => {
    var t;
    return (t = r.current.find((n) => n != null && n.isConnected)) != null ? t : null;
  });
}
function Y(e, { ownerDocument: r }) {
  let t = !!(e & 8), n = X(t);
  g(() => {
    t || (r == null ? void 0 : r.activeElement) === (r == null ? void 0 : r.body) && l(n());
  }, [t]), U(() => {
    t && l(n());
  });
}
function ee(e, { ownerDocument: r, container: t, initialFocus: n, initialFocusFallback: u }) {
  let s = w(null), m = M(!!(e & 1), "focus-trap#initial-focus"), o = I();
  return g(() => {
    if (e === 0) return;
    if (!m) {
      u != null && u.current && l(u.current);
      return;
    }
    let i = t.current;
    i && P(() => {
      if (!o.current) return;
      let a = r == null ? void 0 : r.activeElement;
      if (n != null && n.current) {
        if ((n == null ? void 0 : n.current) === a) {
          s.current = a;
          return;
        }
      } else if (i.contains(a)) {
        s.current = a;
        return;
      }
      if (n != null && n.current) l(n.current);
      else {
        if (e & 16) {
          if (v(i, f.First | f.AutoFocus) !== H.Error) return;
        } else if (v(i, f.First) !== H.Error) return;
        if (u != null && u.current && (l(u.current), (r == null ? void 0 : r.activeElement) === u.current)) return;
        console.warn("There are no focusable elements inside the <FocusTrap />");
      }
      s.current = r == null ? void 0 : r.activeElement;
    });
  }, [u, m, e]), s;
}
function te(e, { ownerDocument: r, container: t, containers: n, previousActiveElement: u }) {
  let s = I(), m = !!(e & 4);
  K(r == null ? void 0 : r.defaultView, "focus", (o) => {
    if (!m || !s.current) return;
    let i = S(n);
    t.current instanceof HTMLElement && i.add(t.current);
    let a = u.current;
    if (!a) return;
    let d = o.target;
    d && d instanceof HTMLElement ? B(i, d) ? (u.current = d, l(d)) : (o.preventDefault(), o.stopPropagation(), l(a)) : l(u.current);
  }, !0);
}
function B(e, r) {
  for (let t of e) if (t.contains(r)) return !0;
  return !1;
}
export {
  be as FocusTrap,
  x as FocusTrapFeatures
};
