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 useCraneEventManager() {
    const { craneStore, productStore, assetStore, vehicleStore, armBotStore, machineStore, craneEventManagerRef } = useSceneContext();
    const { getCraneById, setCurrentPhase, removeCurrentAction } = craneStore();
    const { getAssetById } = assetStore();
    const { getVehicleById } = vehicleStore();
    const { getArmBotById } = armBotStore();
    const { getMachineById } = machineStore();
    const { getActionByUuid, getEventByModelUuid } = productStore();
    const { selectedProductStore } = useProductContext();
    const { selectedProduct } = selectedProductStore();

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

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

    const addCraneToMonitor = (craneId: string, callback: () => void, actionUuid: string) => {
        const crane = getCraneById(craneId);
        const action = getActionByUuid(selectedProduct.productUuid, actionUuid) as CraneAction | undefined;

        if (!crane || !action || action.actionType !== 'pickAndDrop' || !craneEventManagerRef.current) return;

        let state = craneEventManagerRef.current.craneStates.find(c => c.craneId === craneId);
        if (!state) {
            state = {
                craneId,
                pendingActions: [],
                currentAction: null,
                isProcessing: false
            };
            craneEventManagerRef.current.craneStates.push(state);
        }

        state.pendingActions.push({
            actionUuid,
            callback
        });

        if (!state.isProcessing) {
            processNextAction(state);
        }
    };

    const processNextAction = (state: CraneEventState) => {
        if (state.pendingActions.length === 0) {
            state.currentAction = null;
            return;
        }

        state.isProcessing = true;
        state.currentAction = state.pendingActions.shift() || null;
    };

    const completeCurrentAction = (state: CraneEventState) => {
        processNextAction(state);
    };

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

        for (const craneState of craneEventManagerRef.current.craneStates) {
            if (!craneState.currentAction || !craneState.isProcessing) continue;

            const { craneId, currentAction } = craneState;
            const crane = getCraneById(craneId);
            const craneAsset = getAssetById(craneId);
            const currentCraneAction = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || '') as CraneAction | undefined;

            if (!crane || !craneAsset || !currentCraneAction) continue;
            if (crane.isActive || crane.state !== "idle") continue;

            if (currentCraneAction.actionType === 'pickAndDrop' && crane.currentLoad < currentCraneAction.maxPickUpCount) {
                const humanAction = getActionByUuid(selectedProduct.productUuid, currentCraneAction.triggers[0].triggeredAsset?.triggeredAction?.actionUuid || '');
                if (humanAction) {
                    const nextEvent = getEventByModelUuid(selectedProduct.productUuid, humanAction.triggers[0].triggeredAsset?.triggeredModel?.modelUuid || '')
                    if (nextEvent) {
                        if (nextEvent.type === 'transfer') {
                            if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
                                setCurrentPhase(crane.modelUuid, 'init');
                                removeCurrentAction(crane.modelUuid);
                            }

                            craneState.isProcessing = false;
                            currentAction.callback();

                            setTimeout(() => {
                                completeCurrentAction(craneState);
                            }, 1000);
                        } else if (nextEvent.type === 'vehicle') {
                            const vehicle = getVehicleById(nextEvent.modelUuid);

                            if (vehicle && !vehicle.isActive && vehicle.currentPhase === 'picking') {
                                if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
                                    setCurrentPhase(crane.modelUuid, 'init');
                                    removeCurrentAction(crane.modelUuid);
                                }

                                craneState.isProcessing = false;
                                currentAction.callback();

                                setTimeout(() => {
                                    completeCurrentAction(craneState);
                                }, 1000);
                            }
                        } else if (nextEvent.type === 'roboticArm') {
                            const armBot = getArmBotById(nextEvent.modelUuid);

                            if (armBot && !armBot.isActive) {
                                if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
                                    setCurrentPhase(crane.modelUuid, 'init');
                                    removeCurrentAction(crane.modelUuid);
                                }

                                craneState.isProcessing = false;
                                currentAction.callback();

                                setTimeout(() => {
                                    completeCurrentAction(craneState);
                                }, 1000);
                            }
                        } else if (nextEvent.type === 'machine') {
                            const machine = getMachineById(nextEvent.modelUuid);

                            if (machine && !machine.isActive) {
                                if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
                                    setCurrentPhase(crane.modelUuid, 'init');
                                    removeCurrentAction(crane.modelUuid);
                                }

                                craneState.isProcessing = false;
                                currentAction.callback();

                                setTimeout(() => {
                                    completeCurrentAction(craneState);
                                }, 1000);
                            }
                        } else {
                            if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
                                setCurrentPhase(crane.modelUuid, 'init');
                                removeCurrentAction(crane.modelUuid);
                            }

                            craneState.isProcessing = false;
                            currentAction.callback();

                            setTimeout(() => {
                                completeCurrentAction(craneState);
                            }, 1000);
                        }
                    }
                }
            }
        }
    }, 0);

    return {
        addCraneToMonitor
    };
}