import { useEffect, useRef } from 'react';
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
import { useSceneContext } from '../../../../scene/sceneContext';

interface MachineAnimatorProps {
    currentPhase: string;
    handleCallBack: () => void;
    reset: () => void;
    machineStatus: (modelId: string, status: string) => void;
    processingTime: number;
    machineUuid: string
}

const MachineAnimator = ({ currentPhase, handleCallBack, processingTime, machineUuid, machineStatus, reset }: MachineAnimatorProps) => {
    const animationStarted = useRef<boolean>(false);
    const isPausedRef = useRef<boolean>(false);
    const startTimeRef = useRef<number>(0);
    const animationFrameId = useRef<number | null>(null);
    const pauseTimeRef = useRef<number | null>(null);
    const { isPaused } = usePauseButtonStore();
    const { machineStore } = useSceneContext();
    const { removeCurrentAction } = machineStore();
    const { isReset } = useResetButtonStore();
    const { isPlaying } = usePlayButtonStore();
    const { speed } = useAnimationPlaySpeed();
    const isPlayingRef = useRef<boolean>(false);

    useEffect(() => {
        isPausedRef.current = isPaused;
    }, [isPaused]);

    useEffect(() => {
        isPlayingRef.current = isPlaying;
    }, [isPlaying]);

    useEffect(() => {
        if (isReset || !isPlaying) {
            reset();
            startTimeRef.current = 0;
            isPausedRef.current = false;
            pauseTimeRef.current = 0;
            animationFrameId.current = null;
            animationStarted.current = false;
            removeCurrentAction(machineUuid)
        }
    }, [isReset, isPlaying])

    useEffect(() => {
        if (currentPhase === 'processing' && !animationStarted.current && machineUuid) {
            animationStarted.current = true;
            startTimeRef.current = performance.now();
            animationFrameId.current = requestAnimationFrame(step);
        }

    }, [currentPhase]);

    function step(time: number) {

        if (isPausedRef.current) {
            if (!pauseTimeRef.current) {
                pauseTimeRef.current = performance.now();
            }
            animationFrameId.current = requestAnimationFrame(step);
            return;
        }

        if (pauseTimeRef.current) {
            const pauseDuration = performance.now() - pauseTimeRef.current;
            startTimeRef.current += pauseDuration;
            pauseTimeRef.current = null;
        }

        const elapsed = time - startTimeRef.current;
        const processedTime = (processingTime * 1000) / speed;

        if (elapsed < processedTime) {
            machineStatus(machineUuid, "Machine is currently processing the task");
            animationFrameId.current = requestAnimationFrame(step);
        } else {
            animationStarted.current = false;
            if (animationFrameId.current !== null) {
                removeCurrentAction(machineUuid);
                cancelAnimationFrame(animationFrameId.current);
                animationFrameId.current = null;
                handleCallBack();
            }

        }
    }

    return null;
}

export default MachineAnimator;
