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

type ConveyorCallback = {
    conveyorId: string;
    callback: () => void;
};

export function useConveyorEventManager() {
    const { getConveyorById } = useConveyorStore();
    const callbacksRef = useRef<ConveyorCallback[]>([]);
    const isMonitoringRef = useRef(false);
    const { isPlaying } = usePlayButtonStore();
    const { isPaused } = usePauseButtonStore();
    const { isReset } = useResetButtonStore();

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

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

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

    // Remove a conveyor from monitoring
    const removeConveyorFromMonitor = (conveyorId: string) => {
        callbacksRef.current = callbacksRef.current.filter(
            (entry) => entry.conveyorId !== conveyorId
        );

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

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

        callbacksRef.current.forEach(({ conveyorId, callback }) => {
            const conveyor = getConveyorById(conveyorId);
            if (conveyor?.isPaused === false) {
                callback();
                removeConveyorFromMonitor(conveyorId); // Remove after triggering
            }
        });
    });

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

    return {
        addConveyorToMonitor,
        removeConveyorFromMonitor,
    };
}