"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import { inertValue } from "@react-aria/utils";
import { AnimatePresence, motion, useIsPresent } from "motion/react";
import { forwardRef, useRef } from "react";
import { easings } from "./tailwind/theme.js";
import { classNames } from "../utils/classNames.js";
import { getChildrenKey } from "../utils/getChildrenKey.js";
const ExperimentalTransition = forwardRef(
  ({
    layout = "block",
    mode = "cross",
    duration = 300,
    ease = "in-out",
    animateSize = true,
    className,
    children,
    ...props
  }, ref) => {
    const Element = layout === "inline" ? "span" : "div";
    const sizeProperty = animateSize ? layout === "inline" ? "width" : "height" : null;
    const transitionElementsWrapperRef = useRef(null);
    if (duration <= 0) {
      return /* @__PURE__ */ jsx(
        Element,
        {
          ref,
          "data-layout": layout,
          className: classNames([
            `gds-transition isolate
            data-[layout=block]:block
            data-[layout=inline]:inline-block
            data-[layout=flex-col]:flex
            data-[layout=flex-col]:flex-col`,
            className
          ]),
          ...props,
          children
        }
      );
    }
    return /* @__PURE__ */ jsx(
      Element,
      {
        ref,
        "data-layout": layout,
        "data-animate-size": animateSize || void 0,
        className: classNames([
          `gds-transition isolate
          [--gds-transition-state:idle]
          data-[layout=block]:block
          data-[layout=inline]:inline-block
          data-[layout=flex-col]:flex
          data-[layout=flex-col]:flex-col
          -:[--gds-transition-enter-opacity:0]
          -:[--gds-transition-enter-scale:1]
          -:[--gds-transition-enter-translate-x:0]
          -:[--gds-transition-enter-translate-y:0]
          -:[--gds-transition-exit-opacity:0]
          -:[--gds-transition-exit-scale:1]
          -:[--gds-transition-exit-translate-x:0]
          -:[--gds-transition-exit-translate-y:0]
          has-[>*>*>[inert]]:[--gds-transition-state:running]
          data-[animate-size=clip]:has-[>*>*>[inert]]:overflow-clip`,
          className
        ]),
        ...props,
        children: /* @__PURE__ */ jsx(
          Element,
          {
            ref: transitionElementsWrapperRef,
            "data-layout": layout,
            className: `
            gds-transition-elements-wrapper flex [--height:auto] [--shrink:1]
            data-[layout=flex-col]:grow
            data-[layout=block]:flex-col
            data-[layout=flex-col]:flex-col
          `,
            children: /* @__PURE__ */ jsx(
              AnimatePresence,
              {
                initial: false,
                onExitComplete: () => {
                  setTimeout(() => {
                    if (layout === "flex-col" && sizeProperty === "height" && transitionElementsWrapperRef.current) {
                      Array.from(transitionElementsWrapperRef.current.children).forEach((element) => {
                        if (element instanceof HTMLElement) {
                          element.style.removeProperty("--height");
                          element.style.removeProperty("--shrink");
                        }
                      });
                    }
                  }, 0);
                },
                children: /* @__PURE__ */ jsx(
                  motion.span,
                  {
                    transition: { duration: duration / 1e3, ease: typeof ease === "string" ? easings[ease] : ease },
                    initial: sizeProperty ? { [sizeProperty]: 0 } : void 0,
                    animate: sizeProperty ? { [sizeProperty]: "auto" } : void 0,
                    exit: sizeProperty ? { [sizeProperty]: 0 } : void 0,
                    onAnimationStart: (animation) => {
                      if (layout !== "flex-col" || sizeProperty !== "height") return;
                      const animateHeightTo = typeof animation === "object" && "height" in animation ? animation.height : null;
                      if (animateHeightTo !== "auto") return;
                      if (!transitionElementsWrapperRef.current) return;
                      const currentTransitionElements = Array.from(transitionElementsWrapperRef.current.children).filter(
                        (child) => child instanceof HTMLElement
                      );
                      const otherTransitionElements = Array.from(
                        document.querySelectorAll(".gds-transition-elements-wrapper:has(>*>[inert])")
                      ).flatMap((element) => {
                        if (element === transitionElementsWrapperRef.current) return [];
                        return Array.from(element.children).filter((child) => child instanceof HTMLElement);
                      });
                      const currentEnteringElement = currentTransitionElements.find(
                        (element) => element.matches(":not(:has(>[inert]))")
                      );
                      if (!currentEnteringElement) return;
                      const otherEnteringElements = otherTransitionElements.filter(
                        (element) => element.matches(":not(:has(>[inert]))")
                      );
                      const allEnteringElements = [currentEnteringElement, ...otherEnteringElements];
                      const currentExitingElements = currentTransitionElements.filter(
                        (element) => element.matches(":has(>[inert])")
                      );
                      const otherExitingElements = otherTransitionElements.filter(
                        (element) => element.matches(":has(>[inert])")
                      );
                      const allExitingElements = [...currentExitingElements, ...otherExitingElements];
                      allEnteringElements.forEach((enteringElement) => {
                        enteringElement.style.position = "absolute";
                      });
                      currentExitingElements.forEach((currentExitingElement) => {
                        if (!currentExitingElement.style.getPropertyValue("--height")) {
                          currentExitingElement.style.setProperty("--height", `${currentExitingElement.offsetHeight}px`);
                          currentExitingElement.style.setProperty("--shrink", "0");
                        }
                      });
                      allEnteringElements.forEach((enteringElement) => {
                        enteringElement.style.position = "";
                        enteringElement.style.setProperty("--previous-height", enteringElement.style.height);
                        enteringElement.style.height = "";
                      });
                      allExitingElements.forEach((exitingElement) => {
                        exitingElement.style.width = `${exitingElement.offsetWidth}px`;
                        exitingElement.style.height = `${exitingElement.offsetHeight}px`;
                        exitingElement.style.position = "absolute";
                      });
                      if (!currentEnteringElement.style.getPropertyValue("--height")) {
                        currentEnteringElement.style.setProperty("--height", `${currentEnteringElement.offsetHeight}px`);
                        currentEnteringElement.style.setProperty("--shrink", "0");
                      }
                      allExitingElements.forEach((exitingElement) => {
                        exitingElement.style.width = "";
                        exitingElement.style.height = "";
                        exitingElement.style.position = "";
                      });
                      allEnteringElements.forEach((enteringElement) => {
                        enteringElement.style.height = enteringElement.style.getPropertyValue("--previous-height");
                      });
                    },
                    "data-layout": layout,
                    "data-animate-size": animateSize || void 0,
                    className: `
                static block
                data-[layout=flex-col]:flex
                data-[layout=flex-col]:data-[animate-size]:grow
                data-[layout=flex-col]:flex-col
                data-[layout=flex-col]:data-[animate-size]:has-[>[inert]]:shrink-[9999]
                not-has-[>[inert]]:order-first
                data-[layout=flex-col]:not-has-[>[inert]]:grow
              `,
                    children: /* @__PURE__ */ jsx(TransitionContent, { layout, mode, duration, ease, children })
                  },
                  getChildrenKey(children)
                )
              }
            )
          }
        )
      }
    );
  }
);
ExperimentalTransition.displayName = "ExperimentalTransition";
function TransitionContent({
  layout,
  mode,
  duration,
  ease,
  children
}) {
  const isPresent = useIsPresent();
  const enterOpacity = "var(--gds-transition-enter-opacity)";
  const enterTranslateX = "var(--gds-transition-enter-translate-x)";
  const enterTranslateY = "var(--gds-transition-enter-translate-y)";
  const enterScale = "var(--gds-transition-enter-scale)";
  const exitOpacity = "var(--gds-transition-exit-opacity)";
  const exitTranslateX = "var(--gds-transition-exit-translate-x)";
  const exitTranslateY = "var(--gds-transition-exit-translate-y)";
  const exitScale = "var(--gds-transition-exit-scale)";
  const enterTimes = (() => {
    switch (mode) {
      case "cross":
        return [0, 1];
      case "exit-enter":
        return [0.5, 1];
      case "enter-exit":
        return [0, 0.5];
      default:
        return mode.enter;
    }
  })();
  const exitTimes = (() => {
    switch (mode) {
      case "cross":
        return [0, 1];
      case "exit-enter":
        return [0, 0.5];
      case "enter-exit":
        return [0.5, 1];
      default:
        return mode.exit;
    }
  })();
  return /* @__PURE__ */ jsxs(
    motion.span,
    {
      initial: {
        /**
         * Animating `opacity` directly seems buggy with multiple keyframes (e.g. the enter opacity is not synced with
         * the enter transforms in `exit-enter` mode). TODO: Report bug.
         */
        "--opacity": enterOpacity,
        x: enterTranslateX,
        y: enterTranslateY,
        scale: enterScale
      },
      animate: {
        "--opacity": 1,
        x: 0,
        y: 0,
        scale: 1,
        transition: {
          duration: duration / 1e3,
          ease: typeof ease === "string" ? easings[ease] : ease,
          times: enterTimes
        }
      },
      exit: {
        "--opacity": exitOpacity,
        x: exitTranslateX,
        y: exitTranslateY,
        scale: exitScale,
        "--position": "absolute",
        transition: {
          duration: duration / 1e3,
          ease: typeof ease === "string" ? easings[ease] : ease,
          times: exitTimes
        }
      },
      inert: inertValue(!isPresent),
      "data-layout": layout,
      className: `
        nested/transition-content block opacity-[var(--opacity)] [--position:relative]
        data-[layout=flex-col]:flex
        data-[layout=flex-col]:h-[var(--height)]
        data-[layout=inline]:w-max
        data-[layout=flex-col]:shrink-[var(--shrink)]
        data-[layout=flex-col]:grow
        data-[layout=flex-col]:flex-col
        inert:inset-0
        inert:[position:var(--position)]
        not-inert:z-10
      `,
      children: [
        children,
        !children || typeof children === "string" && children.trim() === "" ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "block size-px [:not([inert])>&]:absolute" }) : null
      ]
    }
  );
}
export {
  ExperimentalTransition
};
