import React, { useCallback, useEffect, useRef, useState } from 'react';
import VehicleAnimator from '../animator/vehicleAnimator';
import * as THREE from 'three';
import { NavMeshQuery } from '@recast-navigation/core';
import { useNavMesh } from '../../../../../store/store';
import { usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore';
import MaterialAnimator from '../animator/materialAnimator';

function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) {
    const { navMesh } = useNavMesh();
    const vehicleRef: any = useRef();
    const { isPlaying } = usePlayButtonStore();
    const { vehicles, setVehicleActive, setVehicleState, incrementVehicleLoad, setMaterialType } = useVehicleStore();
    const [currentPhase, setCurrentPhase] = useState<string>('stationed');
    const [path, setPath] = useState<[number, number, number][]>([]);
    let isIncrememtable = useRef<boolean>(true);

    const computePath = useCallback(
        (start: any, end: any) => {
            try {
                const navMeshQuery = new NavMeshQuery(navMesh);
                const { path: segmentPath } = navMeshQuery.computePath(start, end);
                return (
                    segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || []
                );
            } catch {
                return [];
            }
        },
        [navMesh]
    );

    function vehicleStatus(modelId: string, status: string) {
        // console.log(`${modelId} , ${status}`);

    }

    // Function to reset everything
    function reset() {
        setCurrentPhase('stationed');
        setVehicleActive(agvDetail.modelUuid, false);
        setVehicleState(agvDetail.modelUuid, 'idle');
        setPath([]);
    }

    const increment = () => {
        if (isIncrememtable.current) {
            incrementVehicleLoad(agvDetail.modelUuid, 10);
            setMaterialType(agvDetail.modelUuid, 'Material 1')
            isIncrememtable.current = false;
        }
    }

    useEffect(() => {
        if (isPlaying) {

            if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'stationed') {
                const toPickupPath = computePath(
                    new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2]),
                    agvDetail?.point?.action?.pickUpPoint?.position
                );
                setPath(toPickupPath);
                setCurrentPhase('stationed-pickup');
                setVehicleState(agvDetail.modelUuid, 'running');
                setVehicleActive(agvDetail.modelUuid, true);
                vehicleStatus(agvDetail.modelUuid, 'Started from station, heading to pickup');
                return;
            } else if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'picking') {

                setTimeout(() => {
                    increment();
                }, 5000);


                if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity && agvDetail.materialType) {
                    if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) {
                        const toDrop = computePath(
                            agvDetail.point.action.pickUpPoint.position,
                            agvDetail.point.action.unLoadPoint.position
                        );
                        setPath(toDrop);
                        setCurrentPhase('pickup-drop');
                        setVehicleState(agvDetail.modelUuid, 'running');
                        setVehicleActive(agvDetail.modelUuid, true);
                        vehicleStatus(agvDetail.modelUuid, 'Started from pickup point, heading to drop point');
                    }
                }
            } else if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'dropping' && agvDetail.currentLoad === 0) {
                if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) {
                    const dropToPickup = computePath(
                        agvDetail.point.action.unLoadPoint.position,
                        agvDetail.point.action.pickUpPoint.position
                    );
                    setPath(dropToPickup);
                    setCurrentPhase('drop-pickup');
                    setVehicleState(agvDetail.modelUuid, 'running');
                    setVehicleActive(agvDetail.modelUuid, true);
                    vehicleStatus(agvDetail.modelUuid, 'Started from dropping point, heading to pickup point');

                    isIncrememtable.current = true;
                }
            }
        } else {
            reset()
        }
    }, [vehicles, currentPhase, path, isPlaying]);

    function handleCallBack() {
        if (currentPhase === 'stationed-pickup') {
            setCurrentPhase('picking');
            setVehicleState(agvDetail.modelUuid, 'idle');
            setVehicleActive(agvDetail.modelUuid, false);
            vehicleStatus(agvDetail.modelUuid, 'Reached pickup point, waiting for material');
            setPath([]);
        } else if (currentPhase === 'pickup-drop') {
            setCurrentPhase('dropping');
            setVehicleState(agvDetail.modelUuid, 'idle');
            setVehicleActive(agvDetail.modelUuid, false);
            vehicleStatus(agvDetail.modelUuid, 'Reached drop point');
            setPath([]);
        } else if (currentPhase === 'drop-pickup') {
            setCurrentPhase('picking');
            setVehicleState(agvDetail.modelUuid, 'idle');
            setVehicleActive(agvDetail.modelUuid, false);
            setPath([]);
            setMaterialType(agvDetail.modelUuid, null)
            vehicleStatus(agvDetail.modelUuid, 'Reached pickup point again, cycle complete');
        }
    }

    return (
        <>
            <VehicleAnimator
                path={path}
                handleCallBack={handleCallBack}
                currentPhase={currentPhase}
                agvUuid={agvDetail?.modelUuid}
                agvDetail={agvDetail}
                reset={reset}
            />
            <MaterialAnimator agvDetail={agvDetail} />
        </>
    );
}

export default VehicleInstance;