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";

interface SimulationUsageRecord {
    activeTime: number;
    isActive: boolean;
    idleTime: number;
    type: "roboticArm" | "vehicle" | "transfer" | "storageUnit" | "crane" | "human" | "machine";
    assetId: string;
}

// Product → holds multiple usage records
interface ProductSimulation {
    productId: string;
    data: SimulationUsageRecord[];
}

// Version → holds multiple products
interface VersionSimulation {
    versionId: string;
    products: ProductSimulation[];
}

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 { projectId } = useParams();
    const COST_RATES: Record<SimulationUsageRecord["type"], number> = {
        roboticArm: 5,
        vehicle: 2,
        transfer: 1,
        storageUnit: 1,
        crane: 6,
        human: 4,
        machine: 3,
    };
    const { selectedVersion } = versionStore();

    // Calculate totals for one product
    function calculateProductMetrics(product: ProductSimulation) {
        let totalActiveTime = 0;
        let totalIdleTime = 0;
        let totalCost = 0;

        product.data.forEach((record) => {
            const resourceTime = record.activeTime + record.idleTime;
            const costRate = COST_RATES[record.type] || 0;

            totalActiveTime += record.activeTime;
            totalIdleTime += record.idleTime;
            totalCost += resourceTime * costRate;
        });

        return {
            totalTime: totalActiveTime + totalIdleTime,
            totalActiveTime,
            totalIdleTime,
            totalCost,
        };
    }

    // Calculate totals for a version
    function calculateVersionMetrics(version: VersionSimulation) {
        return version.products.reduce(
            (acc, product) => {
                const metrics = calculateProductMetrics(product);

                acc.totalTime += metrics.totalTime;
                acc.totalActiveTime += metrics.totalActiveTime;
                acc.totalIdleTime += metrics.totalIdleTime;
                acc.totalCost += metrics.totalCost;
                return acc;
            },
            { totalTime: 0, totalActiveTime: 0, totalIdleTime: 0, totalCost: 0 }
        );
    }

    // Efficiency score (compare across versions)
    function calculateEfficiencyScores(versions: VersionSimulation[]) {
        const versionMetrics = versions.map((v) => ({
            versionId: v.versionId,
            ...calculateVersionMetrics(v),
        }));

        const minTime = Math.min(...versionMetrics.map((m) => m.totalTime));
        const minCost = Math.min(...versionMetrics.map((m) => m.totalCost));

        return versionMetrics.map((m) => {
            const timeFactor = minTime / m.totalTime;
            const costFactor = minCost / m.totalCost;

            const efficiencyScore = 0.5 * timeFactor + 0.5 * costFactor;

            return { ...m, efficiencyScore };
        });
    }

    useEffect(() => {
        let checkTimer: ReturnType<typeof setTimeout>;
        if (!projectId) return;
        async function checkActiveMachines() {
            const currentProduct = getProductById(selectedProduct.productUuid);
            let hasActiveEntity = false;

            if (currentProduct) {
                const executionSequences = await determineExecutionMachineSequences([currentProduct]);
                if (executionSequences?.length > 0) {
                    executionSequences.forEach((sequence) => {
                        sequence.forEach((entity) => {
                            if (entity.type === "roboticArm") {
                                const roboticArm = getArmBotById(entity.modelUuid);
                                if (roboticArm?.isActive) {
                                    hasActiveEntity = true;
                                }
                            }
                            if (entity.type === "vehicle") {
                                const vehicle = getVehicleById(entity.modelUuid);
                                if (vehicle?.isActive) {
                                    hasActiveEntity = true;
                                }
                            }
                            if (entity.type === "machine") {
                                const machine = getMachineById(entity.modelUuid);
                                if (machine?.isActive) {
                                    hasActiveEntity = true;
                                }
                            }
                            if (entity.type === "human") {
                                const human = getHumanById(entity.modelUuid);
                                if (human?.isActive) {
                                    hasActiveEntity = true;
                                }
                            }
                            if (entity.type === "crane") {
                                const crane = getCraneById(entity.modelUuid);
                                if (crane?.isActive) {
                                    hasActiveEntity = true;
                                }
                            }
                            if (entity.type === "storageUnit") {
                                const storageUnit = getStorageUnitById(entity.modelUuid);
                                if (storageUnit?.isActive) {
                                    hasActiveEntity = true;
                                }
                            }
                            if (entity.type === "transfer") {
                                const storageUnit = getConveyorById(entity.modelUuid);
                                if (storageUnit?.isActive) {
                                    hasActiveEntity = true;
                                }
                            }
                        });
                    });
                }

                if (materials.length === 0 && materialHistory.length >= 0 && !hasActiveEntity) {
                    if (!selectedVersion) return;
                    resetProductRecords(projectId, selectedVersion?.versionId, selectedProduct?.productUuid);
                    if (executionSequences?.length > 0) {
                        executionSequences.forEach((sequence) => {
                            sequence.forEach((entity) => {
                                const typeToGetter: Record<string, (id: string) => any> = {
                                    roboticArm: getArmBotById,
                                    vehicle: getVehicleById,
                                    machine: getMachineById,
                                    human: getHumanById,
                                    crane: getCraneById,
                                    storageUnit: getStorageUnitById,
                                    transfer: getConveyorById,
                                };

                                const getter = typeToGetter[entity.type];
                                if (!getter) return; // skip unknown entity types

                                const obj = getter(entity.modelUuid);
                                if (!obj) return; // skip if not found

                                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,
                                });
                            });
                        });
                    }
                    const data = {
                        projectId: projectId,
                        versionId: selectedVersion?.versionId,
                        productUuid: selectedProduct.productUuid,
                        simulateData: useSimulationManager.getState().getProductById(projectId || "", selectedVersion?.versionId || "", selectedProduct?.productUuid || "")?.simulateData,
                    };
                    const simulations = await saveSimulationDataApi(data);

                    echo.log("Simulation data saved successfully");
                    setIsPlaying(false);
                }
            }
        }

        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;
