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

export function useHumanEventManager() {
    const { humanStore, productStore, assetStore, humanEventManagerRef } = useSceneContext();
    const { getHumanById, setCurrentPhase, removeCurrentAction } = humanStore();
    const { getAssetById } = assetStore();
    const { getActionByUuid } = productStore();
    const { selectedProductStore } = useProductContext();
    const { selectedProduct } = selectedProductStore();

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

    useEffect(() => {
        if ((isReset || !isPlaying) && humanEventManagerRef.current) {
            humanEventManagerRef.current.humanStates = [];
        }
    }, [isReset, isPlaying]);

    const addHumanToMonitor = (humanId: string, callback: () => void, actionUuid: string) => {
        const human = getHumanById(humanId);
        const action = getActionByUuid(selectedProduct.productUuid, actionUuid);
        if (!human || !action || (action.actionType !== 'manufacturer' && action.actionType !== 'worker' && action.actionType !== 'operator') || !humanEventManagerRef.current) return;

        let state = humanEventManagerRef.current.humanStates.find(h => h.humanId === humanId);
        if (!state) {
            state = { humanId, actionQueue: [], isCooldown: false };
            humanEventManagerRef.current.humanStates.push(state);
        }

        const existingAction = state.actionQueue.find(a => a.actionUuid === actionUuid);
        if (existingAction) {
            const currentCount = existingAction.count ?? 0;
            if (existingAction.actionType === 'worker' || existingAction.actionType === 'operator') {
                if (currentCount < existingAction.maxLoadCount) {
                    existingAction.callback = callback;
                    existingAction.isMonitored = true;
                    existingAction.isCompleted = false;
                }
            } else if (existingAction.actionType === 'manufacturer') {
                if (currentCount < existingAction.maxManufactureCount) {
                    existingAction.callback = callback;
                    existingAction.isMonitored = true;
                    existingAction.isCompleted = false;
                }
            }
            return;
        }

        state.actionQueue.push({
            actionType: action.actionType,
            actionUuid,
            actionName: action.actionName,
            maxLoadCount: action.loadCount ?? 0,
            maxManufactureCount: action.manufactureCount ?? 0,
            count: 0,
            isMonitored: true,
            isCompleted: false,
            callback
        });
    };

    const removeHumanFromMonitor = (humanId: string, actionUuid: string) => {
        if (!humanEventManagerRef.current) return;
        const state = humanEventManagerRef.current.humanStates.find(h => h.humanId === humanId);
        if (!state) return;

        const action = state.actionQueue.find(a => a.actionUuid === actionUuid);
        if (action) {
            action.callback = undefined;
            action.isMonitored = false;
        }
    };

    useFrame(() => {
        if (!humanEventManagerRef.current || humanEventManagerRef.current.humanStates.length === 0 || !isPlaying || isPaused) return;

        for (const humanState of humanEventManagerRef.current.humanStates) {
            if (humanState.isCooldown) continue;

            const { humanId, actionQueue } = humanState;
            if (!actionQueue || actionQueue.length === 0) continue;

            const action = actionQueue.find(a => !a.isCompleted);
            if (!action || !action.isMonitored || !action.callback) continue;

            const human = getHumanById(humanId);
            const humanAsset = getAssetById(humanId);
            const currentAction = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '') as HumanAction | undefined;

            if (!human || !humanAsset || !currentAction) continue;
            if (human.isActive || human.state !== "idle" || humanAsset.animationState?.current !== 'idle') continue;

            let conditionMet = false;

            if (currentAction.actionType === 'worker' || currentAction.actionType === 'operator') {
                if ((action.actionType === 'worker' || action.actionType === 'operator') && human.currentLoad < currentAction.loadCapacity) {
                    conditionMet = true;
                } else if (action.actionType === 'manufacturer') {
                    conditionMet = true;
                }
            } else if (currentAction.actionType === 'manufacturer') {
                if (action.actionType === 'manufacturer') {
                    conditionMet = true;
                } else if ((action.actionType === 'worker' || action.actionType === 'operator') && human.currentLoad < currentAction.loadCapacity) {
                    conditionMet = true;
                }
            }

            if (conditionMet) {
                if (action.actionUuid !== human.currentAction?.actionUuid) {
                    setCurrentPhase(human.modelUuid, 'init');
                    removeCurrentAction(human.modelUuid);
                }

                action.callback();
                action.count = (action.count ?? 0) + 1;
                action.isMonitored = false;
                if (((action.actionType === 'worker' || action.actionType === 'operator') && action.count >= action.maxLoadCount) ||
                    (action.actionType === 'manufacturer' && action.count >= action.maxManufactureCount)) {
                    action.isCompleted = true;
                }
                humanState.isCooldown = true;
                setTimeout(() => {
                    humanState.isCooldown = false;
                }, 1000);

                removeHumanFromMonitor(human.modelUuid, action.actionUuid);
            }
        }
    }, 0);

    return {
        addHumanToMonitor,
        removeHumanFromMonitor
    };
}