import { Children as v, cloneElement as $, useState as E, useRef as N, useEffect as M, useCallback as O, useReducer as T } from "react";
import { flushSync as h } from "react-dom";
import { useComposedRefs as U } from "../../react-compose-refs/dist/index.js";
import { useLayoutEffect as p } from "../../react-use-layout-effect/dist/index.js";
function I(n, t) {
  return T((r, o) => {
    const i = t[r][o];
    return i ?? r;
  }, n);
}
const P = (n) => {
  const { present: t, children: r } = n, o = S(t), i = typeof r == "function" ? r({
    present: o.isPresent
  }) : v.only(r), s = U(o.ref, i.ref);
  return typeof r == "function" || o.isPresent ? /* @__PURE__ */ $(i, {
    ref: s
  }) : null;
};
P.displayName = "Presence";
function S(n) {
  const [t, r] = E(), o = N({}), i = N(n), s = N("none"), l = n ? "mounted" : "unmounted", [f, a] = I(l, {
    mounted: {
      UNMOUNT: "unmounted",
      ANIMATION_OUT: "unmountSuspended"
    },
    unmountSuspended: {
      MOUNT: "mounted",
      ANIMATION_END: "unmounted"
    },
    unmounted: {
      MOUNT: "mounted"
    }
  });
  return M(() => {
    const e = d(o.current);
    s.current = f === "mounted" ? e : "none";
  }, [
    f
  ]), p(() => {
    const e = o.current, c = i.current;
    if (c !== n) {
      const A = s.current, m = d(e);
      n ? a("MOUNT") : m === "none" || (e == null ? void 0 : e.display) === "none" ? a("UNMOUNT") : a(c && A !== m ? "ANIMATION_OUT" : "UNMOUNT"), i.current = n;
    }
  }, [
    n,
    a
  ]), p(() => {
    if (t) {
      const e = (u) => {
        const m = d(o.current).includes(u.animationName);
        u.target === t && m && h(
          () => a("ANIMATION_END")
        );
      }, c = (u) => {
        u.target === t && (s.current = d(o.current));
      };
      return t.addEventListener("animationstart", c), t.addEventListener("animationcancel", e), t.addEventListener("animationend", e), () => {
        t.removeEventListener("animationstart", c), t.removeEventListener("animationcancel", e), t.removeEventListener("animationend", e);
      };
    } else
      a("ANIMATION_END");
  }, [
    t,
    a
  ]), {
    isPresent: [
      "mounted",
      "unmountSuspended"
    ].includes(f),
    ref: O((e) => {
      e && (o.current = getComputedStyle(e)), r(e);
    }, [])
  };
}
function d(n) {
  return (n == null ? void 0 : n.animationName) || "none";
}
export {
  P as Presence
};
