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

export function useHumanEventManager() {
    const { humanStore } = useSceneContext();
    const { getHumanById } = humanStore();

    const callbacksRef = useRef<Map<string, (() => void)[]>>(new Map());
    const isMonitoringRef = useRef(false);
    const isCooldownRef = useRef<Map<string, boolean>>(new Map());

    const { isPlaying } = usePlayButtonStore();
    const { isPaused } = usePauseButtonStore();
    const { isReset } = useResetButtonStore();

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

    const addHumanToMonitor = (humanId: string, callback: () => void) => {
        if (!callbacksRef.current.has(humanId)) {
            callbacksRef.current.set(humanId, []);
        }
        callbacksRef.current.get(humanId)!.push(callback);

        if (!isMonitoringRef.current) {
            isMonitoringRef.current = true;
        }
    };

    const removeHumanFromMonitor = (humanId: string) => {
        callbacksRef.current.delete(humanId);
        isCooldownRef.current.delete(humanId);

        if (callbacksRef.current.size === 0) {
            isMonitoringRef.current = false;
        }
    };

    useFrame(() => {

        if (!isMonitoringRef.current || !isPlaying || isPaused) return;

        callbacksRef.current.forEach((queue, humanId) => {
            if (queue.length === 0 || isCooldownRef.current.get(humanId)) return;

            const human = getHumanById(humanId);
            const actionType = human?.point.action.actionType;

            let conditionMet = false;

            if (actionType === 'worker') {
                conditionMet = Boolean(
                    human &&
                    human.isActive === false &&
                    human.state === 'idle' &&
                    human.isScheduled === false &&
                    human.currentLoad < human.point.action.loadCapacity
                );
            } else if (actionType === 'assembly') {
                conditionMet = Boolean(
                    human &&
                    human.isActive === false &&
                    human.state === 'idle' &&
                    human.isScheduled === false
                );
            }

            if (conditionMet) {
                const callback = queue.shift();
                if (callback) {
                    callback();

                    if (queue.length === 0) {
                        removeHumanFromMonitor(humanId);
                    } else {
                        isCooldownRef.current.set(humanId, true);
                        setTimeout(() => {
                            isCooldownRef.current.set(humanId, false);
                        }, 1000);
                    }
                }
            }
        });
    });

    useEffect(() => {
        return () => {
            callbacksRef.current.clear();
            isMonitoringRef.current = false;
            isCooldownRef.current.clear();
        };
    }, []);

    return {
        addHumanToMonitor,
        removeHumanFromMonitor,
    };
}
