import * as c from "react";
import { useRef as h, useState as U, useCallback as k, useId as I, useInsertionEffect as T, useMemo as F, useContext as B, cloneElement as D, Children as N, isValidElement as S } from "react";
import { u as A, L as V } from "./LayoutGroupContext-3euHzeKi.js";
import { f as _, u as G, P as H, a as W } from "./SVGVisualElement-aqO4D4Z5.js";
import { u as Y } from "./use-unmount-effect-Wy5iLAex.js";
function K() {
  const n = h(!1);
  return A(() => (n.current = !0, () => {
    n.current = !1;
  }), []), n;
}
function j() {
  const n = K(), [r, e] = U(0), t = k(() => {
    n.current && e(r + 1);
  }, [r]);
  return [k(() => _.postRender(t), [t]), r];
}
class q extends c.Component {
  getSnapshotBeforeUpdate(r) {
    const e = this.props.childRef.current;
    if (e && r.isPresent && !this.props.isPresent) {
      const t = this.props.sizeRef.current;
      t.height = e.offsetHeight || 0, t.width = e.offsetWidth || 0, t.top = e.offsetTop, t.left = e.offsetLeft;
    }
    return null;
  }
  /**
   * Required with getSnapshotBeforeUpdate to stop React complaining.
   */
  componentDidUpdate() {
  }
  render() {
    return this.props.children;
  }
}
function J({ children: n, isPresent: r }) {
  const e = I(), t = h(null), p = h({
    width: 0,
    height: 0,
    top: 0,
    left: 0
  });
  return T(() => {
    const { width: d, height: l, top: a, left: E } = p.current;
    if (r || !t.current || !d || !l)
      return;
    t.current.dataset.motionPopId = e;
    const f = document.createElement("style");
    return document.head.appendChild(f), f.sheet && f.sheet.insertRule(`
          [data-motion-pop-id="${e}"] {
            position: absolute !important;
            width: ${d}px !important;
            height: ${l}px !important;
            top: ${a}px !important;
            left: ${E}px !important;
          }
        `), () => {
      document.head.removeChild(f);
    };
  }, [r]), c.createElement(q, { isPresent: r, childRef: t, sizeRef: p }, c.cloneElement(n, { ref: t }));
}
const v = ({ children: n, initial: r, isPresent: e, onExitComplete: t, custom: p, presenceAffectsLayout: d, mode: l }) => {
  const a = G(Q), E = I(), f = F(
    () => ({
      id: E,
      initial: r,
      isPresent: e,
      custom: p,
      onExitComplete: (o) => {
        a.set(o, !0);
        for (const i of a.values())
          if (!i)
            return;
        t && t();
      },
      register: (o) => (a.set(o, !1), () => a.delete(o))
    }),
    /**
     * If the presence of a child affects the layout of the components around it,
     * we want to make a new context value to ensure they get re-rendered
     * so they can detect that layout change.
     */
    d ? void 0 : [e]
  );
  return F(() => {
    a.forEach((o, i) => a.set(i, !1));
  }, [e]), c.useEffect(() => {
    !e && !a.size && t && t();
  }, [e]), l === "popLayout" && (n = c.createElement(J, { isPresent: e }, n)), c.createElement(H.Provider, { value: f }, n);
};
function Q() {
  return /* @__PURE__ */ new Map();
}
const m = (n) => n.key || "";
function X(n, r) {
  n.forEach((e) => {
    const t = m(e);
    r.set(t, e);
  });
}
function Z(n) {
  const r = [];
  return N.forEach(n, (e) => {
    S(e) && r.push(e);
  }), r;
}
const oe = ({ children: n, custom: r, initial: e = !0, onExitComplete: t, exitBeforeEnter: p, presenceAffectsLayout: d = !0, mode: l = "sync" }) => {
  W(!p, "Replace exitBeforeEnter with mode='wait'");
  const a = B(V).forceRender || j()[0], E = K(), f = Z(n);
  let o = f;
  const i = h(/* @__PURE__ */ new Map()).current, g = h(o), C = h(/* @__PURE__ */ new Map()).current, w = h(!0);
  if (A(() => {
    w.current = !1, X(f, C), g.current = o;
  }), Y(() => {
    w.current = !0, C.clear(), i.clear();
  }), w.current)
    return c.createElement(c.Fragment, null, o.map((s) => c.createElement(v, { key: m(s), isPresent: !0, initial: e ? void 0 : !1, presenceAffectsLayout: d, mode: l }, s)));
  o = [...o];
  const x = g.current.map(m), M = f.map(m), O = x.length;
  for (let s = 0; s < O; s++) {
    const u = x[s];
    M.indexOf(u) === -1 && !i.has(u) && i.set(u, void 0);
  }
  return l === "wait" && i.size && (o = []), i.forEach((s, u) => {
    if (M.indexOf(u) !== -1)
      return;
    const P = C.get(u);
    if (!P)
      return;
    const $ = x.indexOf(u);
    let R = s;
    if (!R) {
      const b = () => {
        i.delete(u);
        const z = Array.from(C.keys()).filter((y) => !M.includes(y));
        if (z.forEach((y) => C.delete(y)), g.current = f.filter((y) => {
          const L = m(y);
          return (
            // filter out the node exiting
            L === u || // filter out the leftover children
            z.includes(L)
          );
        }), !i.size) {
          if (E.current === !1)
            return;
          a(), t && t();
        }
      };
      R = c.createElement(v, { key: m(P), isPresent: !1, onExitComplete: b, custom: r, presenceAffectsLayout: d, mode: l }, P), i.set(u, R);
    }
    o.splice($, 0, R);
  }), o = o.map((s) => {
    const u = s.key;
    return i.has(u) ? s : c.createElement(v, { key: m(s), isPresent: !0, presenceAffectsLayout: d, mode: l }, s);
  }), process.env.NODE_ENV !== "production" && l === "wait" && o.length > 1 && console.warn(`You're attempting to animate multiple children within AnimatePresence, but its mode is set to "wait". This will lead to odd visual behaviour.`), c.createElement(c.Fragment, null, i.size ? o : o.map((s) => D(s)));
};
export {
  oe as A
};
