'use client';

import isEmpty from './utils/utils';
import { rippleProps } from './ripple.types';
import { rippleAreaContext } from './ripple-area';
import RippleEffectBuild from './utils/ripple-effect-builder';
import React, {
    ForwardedRef,
    forwardRef,
    JSX,
    useCallback,
    useContext,
    useEffect,
    useRef,
    useState,
    useTransition,
} from 'react';

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

    const LifetimeEnd = useCallback((child: JSX.Element) => {
        if (child.props.endLifetime) {
            child.props.endLifetime();
        }

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

    useEffect(() => {
        if (props.children.length > 0) {
            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 = forwardRef(function Ripple(
    props: rippleProps,
    ref: ForwardedRef<any>,
) {
    const { rippleX, rippleY, rippleS, endLifetime, lifetime } = props;

    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 };
