'use client';

import isEmpty from './utils/utils';
import { RippleProps, RipplesProps } from './ripple.types';
import { rippleAreaContext } from './ripple-area';
import RippleEffectBuild from './utils/ripple-effect-builder';
import React, {
    ReactElement,
    useContext,
    useEffect,
    useRef,
    useState,
    useTransition,
} from 'react';

const Ripples = (props: RipplesProps) => {
    const [ripples, setRipples] = useState({});
    const firstRender = useRef<boolean>(true);
    const [pending, startTransition] = useTransition();

    const LifetimeEnd = (child: ReactElement) => {
        if (child.props.endLifetime) {
            child.props.endLifetime();
        }

        setRipples(state => {
            const children = { ...state };
            delete children[child.key];
            return children;
        });
    };

    useEffect(() => {
        if (props.children.length > 0 && !pending) {
            startTransition(() => {
                if (firstRender.current || isEmpty(ripples)) {
                    setRipples(RippleEffectBuild(props.children, LifetimeEnd));
                    firstRender.current = false;
                } else {
                    setRipples(
                        RippleEffectBuild(props.children, LifetimeEnd, ripples),
                    );
                }
            });
        }
    }, [props.children]);

    return <>{Object.values(ripples)}</>;
};

const Ripple = ({
    rippleX,
    rippleY,
    rippleS,
    endLifetime,
    lifetime,
}: RippleProps) => {
    const clicked = useContext<boolean>(rippleAreaContext);
    const [classes, setClasses] = useState<string>('m3 ripple visible');

    useEffect(() => {
        if (endLifetime !== null && !clicked) {
            setClasses('m3 ripple');
            setTimeout(endLifetime, lifetime);
        }
    }, [clicked, endLifetime]);

    return (
        <span
            className={classes}
            style={{
                left: -(rippleS / 2) + rippleX,
                top: -(rippleS / 2) + rippleY,
                width: rippleS,
                aspectRatio: 1,
            }}
        />
    );
};

export { Ripple, Ripples };
