import React, { useEffect, useState } from "react";
import { useSceneContext } from "../../scene/sceneContext";
import { determineExecutionMachineSequences } from "./functions/determineExecutionMachineSequences";
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
import { useSimulationManager } from "../../../store/rough/useSimulationManagerStore";
import { useParams } from "react-router-dom";
import { saveSimulationDataApi } from "../../../services/simulation/comparison/saveSimulationDataApi";

const SimulationHandler = () => {
    const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, productStore, craneStore, humanStore, versionStore } = useSceneContext();
    const { armBots, getArmBotById } = armBotStore();
    const { vehicles, getVehicleById } = vehicleStore();
    const { getConveyorById } = conveyorStore();
    const { materialHistory, materials } = materialStore();
    const { getProductById, selectedProduct } = productStore();
    const { machines, getMachineById } = machineStore();
    const { getHumanById } = humanStore();
    const { getCraneById } = craneStore();
    const { getStorageUnitById } = storageUnitStore();
    const { isPlaying, setIsPlaying } = usePlayButtonStore();
    const { resetProductRecords, addSimulationRecord } = useSimulationManager();
    const { selectedVersion } = versionStore();
    const { projectId } = useParams();

    useEffect(() => {
        if (!projectId) return;

        let checkTimer: ReturnType<typeof setTimeout>;

        const typeToGetter: Record<string, (id: string) => any> = {
            roboticArm: getArmBotById,
            vehicle: getVehicleById,
            machine: getMachineById,
            human: getHumanById,
            crane: getCraneById,
            storageUnit: getStorageUnitById,
            transfer: getConveyorById,
        };

        const isEntityActive = (entity: any): boolean => {
            const getter = typeToGetter[entity.type];
            const obj = getter?.(entity.modelUuid);
            return obj?.isActive ?? false;
        };

        const recordEntity = (entity: any) => {
            const getter = typeToGetter[entity.type];
            const obj = getter?.(entity.modelUuid);
            if (!obj) return;

            addSimulationRecord(projectId, selectedVersion?.versionId || "", selectedProduct?.productUuid, {
                activeTime: obj.activeTime ?? 0,
                isActive: obj.isActive ?? false,
                idleTime: obj.idleTime ?? 0,
                type: entity.type as "roboticArm" | "vehicle" | "machine" | "human" | "crane" | "storageUnit" | "transfer",
                assetId: entity.modelUuid,
            });
        };

        function checkActiveMachines() {
            const currentProduct = getProductById(selectedProduct.productUuid);
            if (!currentProduct) return;

            determineExecutionMachineSequences([currentProduct]).then((executionSequences) => {
                // --- Check if any entity is active ---
                let hasActiveEntity = false;
                executionSequences?.forEach((sequence) =>
                    sequence.forEach((entity) => {
                        if (isEntityActive(entity)) {
                            hasActiveEntity = true;
                        }
                    })
                );

                // --- Save simulation data if idle ---
                const noMaterials = materials.length === 0;
                const hasHistory = materialHistory.length >= 0;

                if (noMaterials && hasHistory && !hasActiveEntity) {
                    if (!selectedVersion) return;

                    resetProductRecords(projectId, selectedVersion.versionId, selectedProduct.productUuid);

                    executionSequences?.forEach((sequence) => sequence.forEach((entity) => recordEntity(entity)));

                    const data = {
                        projectId,
                        versionId: selectedVersion.versionId,
                        productUuid: selectedProduct.productUuid,
                        simulateData: useSimulationManager.getState().getProductById(projectId, selectedVersion.versionId, selectedProduct.productUuid)?.simulateData,
                    };

                    saveSimulationDataApi(data)
                        .then(() => {
                            echo.log("Simulation data saved successfully");
                            setIsPlaying(false);
                        })
                        .catch((err) => {
                            console.error("Failed to save simulation data:", err);
                        });
                }
            });
        }

        if (isPlaying) {
            checkTimer = setTimeout(checkActiveMachines, 1500);
        }

        return () => {
            if (checkTimer) clearTimeout(checkTimer);
        };
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [materials, materialHistory, selectedVersion, selectedProduct?.productUuid, isPlaying, armBots, vehicles, machines]);

    return null;
};

export default SimulationHandler;
