import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
import { Fragment, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
import { TransitionAnimationTypes } from "../Transition";
import UncontrolledTransition from "../UncontrolledTransition";
import Styles from "./AnimatedEntrance.module.scss";
export var EntranceType;
(function (EntranceType) {
    EntranceType[EntranceType["SLIDE_AND_EXPAND"] = 0] = "SLIDE_AND_EXPAND";
    EntranceType[EntranceType["EXPAND"] = 1] = "EXPAND";
})(EntranceType || (EntranceType = {}));
const CONFIGS_BY_ENTRANCE_TYPE = {
    [EntranceType.SLIDE_AND_EXPAND]: {
        forward: {
            elementEntering: Styles.elementEntering,
            elementExiting: Styles.elementExiting,
        },
        backward: {
            elementEntering: Styles.elementEnteringReverse,
            elementExiting: Styles.elementExitingReverse,
        },
    },
    [EntranceType.EXPAND]: {
        forward: {
            elementEntering: Styles.elementExpanding,
            elementExiting: Styles.elementShrinking,
        },
        backward: {
            elementEntering: Styles.elementExpandingReverse,
            elementExiting: Styles.elementShrinkingReverse,
        },
    },
};
export function AnimatedEntranceItem({ children, noEntranceAnimation, onRemoveChildren, entranceType, }) {
    const uncontRef = useRef(null);
    const [screen, setScreen] = useState(noEntranceAnimation ? children : _jsx(Fragment, {}, "null"));
    console.log(screen, children.key);
    useLayoutEffect(() => {
        if (String(children.key).includes("-nullated") && uncontRef.current) {
            uncontRef.current.setOrientation("backward");
        }
    }, [children.key]);
    useEffect(() => {
        setScreen(String(children.key));
    }, [children.key]);
    useEffect(() => {
        if (screen === null)
            return;
        const x = setTimeout(() => {
            const key = String(typeof screen === "string" ? screen : screen.key);
            if (key === "null" || key.includes("-nullated")) {
                uncontRef.current.sectionRef.current.style.maxHeight = `${uncontRef.current.sectionRef.current.scrollHeight}px`;
                setTimeout(() => {
                    uncontRef.current.sectionRef.current.style.maxHeight = `0px`;
                }, 100);
            }
            else {
                uncontRef.current.sectionRef.current.style.maxHeight = `${uncontRef.current.sectionRef.current.scrollHeight}px`;
                if (!noEntranceAnimation) {
                    const restoreAutoHeight = ({ target, currentTarget, }) => {
                        if (target !== currentTarget)
                            return;
                        uncontRef.current.sectionRef.current.style.removeProperty("max-height");
                        uncontRef.current.sectionRef.current.classList.remove(Styles.maxHeight);
                        uncontRef.current.sectionRef.current.removeEventListener("transitionend", restoreAutoHeight);
                    };
                    uncontRef.current.sectionRef.current.addEventListener("transitionend", restoreAutoHeight);
                }
                else {
                    uncontRef.current.sectionRef.current.style.removeProperty("max-height");
                    uncontRef.current.sectionRef.current.classList.remove(Styles.maxHeight);
                }
            }
        }, 100);
        return () => {
            clearTimeout(x);
        };
    }, [typeof screen === "object" ? screen?.key : screen]);
    const firstRenderClass = useMemo(() => (noEntranceAnimation ? "" : Styles.maxHeight), [screen === null]);
    return (_jsx(UncontrolledTransition, { ref: uncontRef, transitionType: TransitionAnimationTypes.CUSTOM, className: `${Styles.resetHeight} ${firstRenderClass}`, lockTransitionWidth: true, onDiscardStep: (k) => {
            if (k !== "null") {
                onRemoveChildren(k);
                setScreen(null);
            }
        }, config: CONFIGS_BY_ENTRANCE_TYPE[entranceType], children: screen === null ? (_jsx(Fragment, {}, "null")) : typeof screen === "string" ? ((children.key?.endsWith("-nullated") && screen.endsWith("-nullated"))
            ? _jsx(Fragment, {}, children.key + "-null")
            : children) : (screen) }, String(children.key).replace("-nullated", "")));
}
/**
 * Wraps child components to add smooth entry and exit animations.
 * It handles animations automatically when items are added or removed.
 **/
export default function AnimatedEntrance({ children, entranceType = EntranceType.SLIDE_AND_EXPAND, }) {
    const firstRef = useRef(true);
    useEffect(() => {
        firstRef.current = false;
    }, []);
    const prevChildren = useRef([]);
    const childrenDelayed = useMemo(() => {
        const newChildren = children.filter((c) => !prevChildren.current.find((a) => a.key === c.key));
        const filteredOutChildren = prevChildren.current.map((c) => {
            return children.find((a) => a.key === c.key) ? ( // If the previous child still exists, mantain
            c) : (
            // If not, toggle to null to animate exit
            _jsx(Fragment, { children: prevChildren.current.find(a => a.key === c.key) }, String(c.key).includes("-nullated") ? c.key : `${c.key}-nullated`));
        });
        for (let child of newChildren) {
            const previousChildKey = children[children.indexOf(child) - 1]?.key;
            if (previousChildKey) {
                filteredOutChildren.splice(filteredOutChildren.findIndex((a) => a.key === previousChildKey) + 1, 0, child);
            }
            else {
                filteredOutChildren.unshift(child);
            }
        }
        return filteredOutChildren;
    }, [children]);
    prevChildren.current = childrenDelayed;
    console.log(childrenDelayed.map(a => a.key));
    return (_jsx(_Fragment, { children: childrenDelayed.map((child) => (_jsx(AnimatedEntranceItem, { noEntranceAnimation: firstRef.current, entranceType: entranceType, onRemoveChildren: (k) => {
                (prevChildren.current = prevChildren.current.filter((a) => a.key !== String(k) + "-nullated"));
            }, children: children.find((c) => c.key === child.key) || child }, String(child.key).replace("-nullated", "")))) }));
}
//# sourceMappingURL=AnimatedEntrance.js.map