import { useEffect, useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../store/usePlayButtonStore';
import { useSceneContext } from '../../../scene/sceneContext';

type MachineCallback = {
    machineId: string;
    callback: () => void;
};

export function useMachineEventManager() {
    const { machineStore } = useSceneContext();
    const { getMachineById } = machineStore();
    const callbacksRef = useRef<MachineCallback[]>([]);
    const isMonitoringRef = useRef(false);
    const { isPlaying } = usePlayButtonStore();
    const { isPaused } = usePauseButtonStore();
    const { isReset } = useResetButtonStore();

    useEffect(() => {
        if (isReset) {
            callbacksRef.current = [];
        }
    }, [isReset])

    // Add a new machine to monitor
    const addMachineToMonitor = (machineId: string, callback: () => void) => {
        // Avoid duplicates
        if (!callbacksRef.current.some((entry) => entry.machineId === machineId)) {
            callbacksRef.current.push({ machineId, callback });
        }

        // Start monitoring if not already running
        if (!isMonitoringRef.current) {
            isMonitoringRef.current = true;
        }
    };

    // Remove a machine from monitoring
    const removeMachineFromMonitor = (machineId: string) => {
        callbacksRef.current = callbacksRef.current.filter(
            (entry) => entry.machineId !== machineId
        );

        // Stop monitoring if no more machines to track
        if (callbacksRef.current.length === 0) {
            isMonitoringRef.current = false;
        }
    };

    // Check machine states every frame
    useFrame(() => {
        if (!isMonitoringRef.current || callbacksRef.current.length === 0 || !isPlaying || isPaused) return;

        callbacksRef.current.forEach(({ machineId, callback }) => {
            const machine = getMachineById(machineId);
            if (machine && machine.isActive === false && machine.state === 'idle' && !machine.currentAction) {
                callback();
                removeMachineFromMonitor(machineId); // Remove after triggering
            }
        });
    });

    // Cleanup on unmount
    useEffect(() => {
        return () => {
            callbacksRef.current = [];
            isMonitoringRef.current = false;
        };
    }, []);

    return {
        addMachineToMonitor,
        removeMachineFromMonitor,
    };
}