import { useEffect, useRef, useState } from 'react'
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
import MachineAnimator from '../animator/machineAnimator';
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
import { useSceneContext } from '../../../../scene/sceneContext';
import { useProductContext } from '../../../products/productContext';

function MachineInstance({ machineDetail }: { readonly machineDetail: MachineStatus }) {
    const [currentPhase, setCurrentPhase] = useState<string>('idle');
    let isIncrememtable = useRef<boolean>(true);
    const idleTimeRef = useRef<number>(0);
    const activeTimeRef = useRef<number>(0);
    const previousTimeRef = useRef<number | null>(null);
    const animationFrameIdRef = useRef<number | null>(null);
    const isSpeedRef = useRef<number>(0);
    const isPausedRef = useRef<boolean>(false);
    const { isPlaying } = usePlayButtonStore();
    const { machineStore, productStore } = useSceneContext();
    const { selectedProductStore } = useProductContext();
    const { machines, setMachineState, setMachineActive, incrementIdleTime, incrementActiveTime, resetTime } = machineStore();
    const { selectedProduct } = selectedProductStore();
    const { getActionByUuid } = productStore();
    const { triggerPointActions } = useTriggerHandler();
    const { speed } = useAnimationPlaySpeed();
    const { isPaused } = usePauseButtonStore();

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

    useEffect(() => {
        isSpeedRef.current = speed;
    }, [speed]);

    const reset = () => {
        setCurrentPhase("idle");
        setMachineState(machineDetail.modelUuid, 'idle');
        setMachineActive(machineDetail.modelUuid, false);
        isIncrememtable.current = true;
        isPausedRef.current = false;
        resetTime(machineDetail.modelUuid)
        activeTimeRef.current = 0
        idleTimeRef.current = 0
        previousTimeRef.current = null
        if (animationFrameIdRef.current !== null) {
            cancelAnimationFrame(animationFrameIdRef.current)
            animationFrameIdRef.current = null
        }
    }

    function machineStatus(modelId: string, status: string) {
        // console.log(`${modelId} , ${status}`);
    }

    function animate(currentTime: number) {
        if (previousTimeRef.current === null) {
            previousTimeRef.current = currentTime;
        }

        const deltaTime = (currentTime - previousTimeRef.current) / 1000;
        previousTimeRef.current = currentTime;

        if (machineDetail.isActive) {
            if (!isPausedRef.current) {
                activeTimeRef.current += deltaTime * isSpeedRef.current;
                // console.log(' activeTimeRef.current: ', activeTimeRef.current);
            }
        } else {
            if (!isPausedRef.current) {
                idleTimeRef.current += deltaTime * isSpeedRef.current;
                // console.log('idleTimeRef.curre: ', idleTimeRef.current);
            }
        }
        animationFrameIdRef.current = requestAnimationFrame(animate);
    }

    useEffect(() => {
        if (!isPlaying) return
        if (!machineDetail.isActive) {
            const roundedActiveTime = Math.round(activeTimeRef.current);
            // console.log('Final Active Time:', roundedActiveTime, 'seconds');
            incrementActiveTime(machineDetail.modelUuid, roundedActiveTime);
            activeTimeRef.current = 0;
        } else {
            const roundedIdleTime = Math.round(idleTimeRef.current);
            // console.log('Final Idle Time:', roundedIdleTime, 'seconds');
            incrementIdleTime(machineDetail.modelUuid, roundedIdleTime);
            idleTimeRef.current = 0;
        }

        if (animationFrameIdRef.current === null) {
            animationFrameIdRef.current = requestAnimationFrame(animate);
        }

        return () => {
            if (animationFrameIdRef.current !== null) {
                cancelAnimationFrame(animationFrameIdRef.current);
                animationFrameIdRef.current = null;
            }
        };
    }, [machineDetail, isPlaying]);

    useEffect(() => {
        if (isPlaying) {
            if (!machineDetail.isActive && machineDetail.state === "idle" && currentPhase == "idle" && !machineDetail.currentAction) {
                machineStatus(machineDetail.modelUuid, 'Machine is idle and waiting for next instruction.')
            } else if (!machineDetail.isActive && machineDetail.state === "idle" && currentPhase == "idle" && machineDetail.currentAction) {
                setCurrentPhase("processing");
                setMachineState(machineDetail.modelUuid, 'running');
                setMachineActive(machineDetail.modelUuid, true);
                machineStatus(machineDetail.modelUuid, "Machine started processing")
            }
        }
    }, [currentPhase, isPlaying, machines])

    function handleCallBack() {
        if (currentPhase == "processing") {
            setMachineState(machineDetail.modelUuid, 'idle');
            setMachineActive(machineDetail.modelUuid, false);
            setCurrentPhase("idle")
            isIncrememtable.current = true;
            machineStatus(machineDetail.modelUuid, "Machine has completed the processing")

            if (machineDetail.currentAction) {
                const action = getActionByUuid(selectedProduct.productUuid, machineDetail.currentAction.actionUuid);
                if (action && machineDetail.currentAction.materialId) {
                    triggerPointActions(action, machineDetail.currentAction.materialId)
                }
            }
        }
    }

    return (
        <>

            <MachineAnimator processingTime={machineDetail.point.action.processTime} handleCallBack={handleCallBack} currentPhase={currentPhase} machineUuid={machineDetail.modelUuid} machineStatus={machineStatus} reset={reset} />

        </>
    )
}

export default MachineInstance