import { useEffect, useCallback, useRef } from "react";
import { useSceneContext } from "../../scene/sceneContext";
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";

function Analyzer() {
    const { isPlaying } = usePlayButtonStore();
    const { conveyorStore, machineStore, armBotStore, humanStore, vehicleStore, craneStore, storageUnitStore, analysisStore } = useSceneContext();

    const { conveyors } = conveyorStore();
    const { machines } = machineStore();
    const { armBots } = armBotStore();
    const { humans } = humanStore();
    const { vehicles } = vehicleStore();
    const { cranes } = craneStore();
    const { storageUnits } = storageUnitStore();

    const { setAnalysis, setAnalyzing } = analysisStore();

    const analysisIntervalRef = useRef<NodeJS.Timeout | null>(null);
    const startTimeRef = useRef<string>(new Date().toISOString());

    // ============================================================================
    // CALCULATION UTILITIES
    // ============================================================================

    const calculateTimeMetrics = (idleTime: number, activeTime: number, totalErrors: number = 0) => {
        const totalTime = idleTime + activeTime;
        const uptime = totalTime > 0 ? (activeTime / totalTime) * 100 : 0;
        const downtime = idleTime;
        const utilizationRate = uptime / 100;

        return {
            uptime,
            downtime,
            utilizationRate,
            mtbf: totalErrors > 0 ? totalTime / totalErrors : totalTime,
            mttr: totalErrors > 0 ? downtime / totalErrors : 0,
        };
    };

    const calculateOEE = (availability: number, performance: number, quality: number) => {
        return (availability * performance * quality) / 10000; // All in percentages
    };

    // ============================================================================
    // CONVEYOR ANALYSIS
    // ============================================================================

    const analyzeConveyor = useCallback((conveyor: any): ConveyorAnalysis => {
        const timeMetrics = calculateTimeMetrics(conveyor.idleTime || 0, conveyor.activeTime || 0);

        const totalTime = (conveyor.idleTime || 0) + (conveyor.activeTime || 0);
        const materialsProcessed = conveyor.materialsProcessed || 0;

        return {
            assetId: conveyor.modelUuid,
            assetName: conveyor.modelName,
            assetType: "conveyor",

            currentStatus: {
                isActive: conveyor.isActive || false,
                isPaused: conveyor.isPaused || false,
                state: conveyor.state || "idle",
                speed: conveyor.speed || 0,
                currentProduct: conveyor.productUuid || null,
            },

            timeMetrics: {
                ...timeMetrics,
                idleTime: conveyor.idleTime || 0,
                activeTime: conveyor.activeTime || 0,
                totalTime,
            },

            throughput: {
                itemsPerHour: totalTime > 0 ? (materialsProcessed / totalTime) * 3600 : 0,
                itemsPerDay: totalTime > 0 ? (materialsProcessed / totalTime) * 86400 : 0,
                materialFlowRate: conveyor.speed || 0,
                capacityUtilization: timeMetrics.utilizationRate * 100,
                materialsProcessed,
                averageProcessingTime: materialsProcessed > 0 ? totalTime / materialsProcessed : 0,
            },

            efficiency: {
                overallEffectiveness: calculateOEE(timeMetrics.uptime, 100, 100),
                availability: timeMetrics.uptime,
                performance: 100,
                quality: 100,
            },

            quality: {
                errorRate: 0,
                errorFrequency: 0,
                successRate: 100,
                stateTransitions: [],
            },

            historicalData: [],
        };
    }, []);

    // ============================================================================
    // VEHICLE ANALYSIS
    // ============================================================================

    const analyzeVehicle = useCallback((vehicle: any): VehicleAnalysis => {
        const timeMetrics = calculateTimeMetrics(vehicle.idleTime || 0, vehicle.activeTime || 0);

        const totalTime = (vehicle.idleTime || 0) + (vehicle.activeTime || 0);
        const tripsCompleted = vehicle.tripsCompleted || 0;

        return {
            assetId: vehicle.modelUuid,
            assetName: vehicle.modelName,
            assetType: "vehicle",

            currentStatus: {
                isActive: vehicle.isActive || false,
                isPicking: vehicle.isPicking || false,
                currentPhase: vehicle.currentPhase || "idle",
                state: vehicle.state || "idle",
                speed: vehicle.speed || 0,
                currentLoad: vehicle.currentLoad || 0,
                currentMaterials: vehicle.currentMaterials || [],
            },

            timeMetrics: {
                ...timeMetrics,
                idleTime: vehicle.idleTime || 0,
                activeTime: vehicle.activeTime || 0,
                totalTime,
                averageTripTime: tripsCompleted > 0 ? totalTime / tripsCompleted : 0,
            },

            throughput: {
                itemsPerHour: totalTime > 0 ? ((vehicle.currentLoad || 0) / totalTime) * 3600 : 0,
                itemsPerDay: totalTime > 0 ? ((vehicle.currentLoad || 0) / totalTime) * 86400 : 0,
                materialFlowRate: vehicle.speed || 0,
                capacityUtilization: timeMetrics.utilizationRate * 100,
                tripsCompleted,
                averageLoadsPerTrip: tripsCompleted > 0 ? (vehicle.totalLoadsDelivered || 0) / tripsCompleted : 0,
                totalLoadsDelivered: vehicle.totalLoadsDelivered || 0,
            },

            movementMetrics: {
                distanceTraveled: vehicle.distanceTraveled || 0,
                averageSpeedActual: totalTime > 0 ? (vehicle.distanceTraveled || 0) / totalTime : 0,
                fuelEfficiency: 0,
                routeEfficiency: 100,
            },

            efficiency: {
                overallEffectiveness: calculateOEE(timeMetrics.uptime, 100, 100),
                availability: timeMetrics.uptime,
                performance: 100,
                quality: 100,
                loadUtilization: vehicle.point?.action?.loadCapacity > 0 ? ((vehicle.currentLoad || 0) / vehicle.point.action.loadCapacity) * 100 : 0,
            },

            quality: {
                errorRate: 0,
                errorFrequency: 0,
                successRate: 100,
                stateTransitions: [],
            },

            historicalData: [],
        };
    }, []);

    // ============================================================================
    // ROBOTIC ARM ANALYSIS
    // ============================================================================

    const analyzeRoboticArm = useCallback((armBot: any): RoboticArmAnalysis => {
        const timeMetrics = calculateTimeMetrics(armBot.idleTime || 0, armBot.activeTime || 0);

        const totalTime = (armBot.idleTime || 0) + (armBot.activeTime || 0);
        const cyclesCompleted = armBot.cyclesCompleted || 0;

        return {
            assetId: armBot.modelUuid,
            assetName: armBot.modelName,
            assetType: "roboticArm",

            currentStatus: {
                isActive: armBot.isActive || false,
                state: armBot.state || "idle",
                speed: armBot.speed || 0,
                currentAction: armBot.currentAction || null,
            },

            timeMetrics: {
                ...timeMetrics,
                idleTime: armBot.idleTime || 0,
                activeTime: armBot.activeTime || 0,
                totalTime,
                averageCycleTime: cyclesCompleted > 0 ? totalTime / cyclesCompleted : 0,
            },

            throughput: {
                itemsPerHour: totalTime > 0 ? (cyclesCompleted / totalTime) * 3600 : 0,
                itemsPerDay: totalTime > 0 ? (cyclesCompleted / totalTime) * 86400 : 0,
                materialFlowRate: armBot.speed || 0,
                capacityUtilization: timeMetrics.utilizationRate * 100,
                cyclesCompleted,
                pickAndPlaceCount: cyclesCompleted,
            },

            efficiency: {
                overallEffectiveness: calculateOEE(timeMetrics.uptime, 100, 100),
                availability: timeMetrics.uptime,
                performance: 100,
                quality: 100,
                cycleTimeEfficiency: 100,
            },

            quality: {
                errorRate: 0,
                errorFrequency: 0,
                successRate: 100,
                stateTransitions: [],
                pickSuccessRate: 100,
                placeAccuracy: 100,
            },

            historicalData: [],
        };
    }, []);

    // ============================================================================
    // MACHINE ANALYSIS
    // ============================================================================

    const analyzeMachine = useCallback((machine: any): MachineAnalysis => {
        const timeMetrics = calculateTimeMetrics(machine.idleTime || 0, machine.activeTime || 0);

        const totalTime = (machine.idleTime || 0) + (machine.activeTime || 0);
        const cyclesCompleted = machine.cyclesCompleted || 0;

        return {
            assetId: machine.modelUuid,
            assetName: machine.modelName,
            assetType: "machine",

            currentStatus: {
                isActive: machine.isActive || false,
                state: machine.state || "idle",
                currentAction: machine.currentAction || null,
            },

            timeMetrics: {
                ...timeMetrics,
                idleTime: machine.idleTime || 0,
                activeTime: machine.activeTime || 0,
                totalTime,
                averageProcessTime: cyclesCompleted > 0 ? totalTime / cyclesCompleted : 0,
            },

            throughput: {
                itemsPerHour: totalTime > 0 ? (cyclesCompleted / totalTime) * 3600 : 0,
                itemsPerDay: totalTime > 0 ? (cyclesCompleted / totalTime) * 86400 : 0,
                materialFlowRate: 1,
                capacityUtilization: timeMetrics.utilizationRate * 100,
                cyclesCompleted,
                partsProcessed: cyclesCompleted,
            },

            efficiency: {
                overallEffectiveness: calculateOEE(timeMetrics.uptime, 100, 100),
                availability: timeMetrics.uptime,
                performance: 100,
                quality: 100,
                targetVsActual: 100,
            },

            quality: {
                errorRate: 0,
                errorFrequency: 0,
                successRate: 100,
                stateTransitions: [],
                defectRate: 0,
                reworkRate: 0,
            },

            historicalData: [],
        };
    }, []);

    // ============================================================================
    // STORAGE ANALYSIS
    // ============================================================================

    const analyzeStorage = useCallback((storage: any): StorageAnalysis => {
        const timeMetrics = calculateTimeMetrics(storage.idleTime || 0, storage.activeTime || 0);

        const utilizationRate = storage.storageCapacity > 0 ? (storage.currentLoad / storage.storageCapacity) * 100 : 0;

        return {
            assetId: storage.modelUuid,
            assetName: storage.modelName,
            assetType: "storage",

            currentStatus: {
                isActive: storage.isActive || false,
                state: storage.state || "idle",
                currentLoad: storage.currentLoad || 0,
                storageCapacity: storage.storageCapacity || 0,
                currentMaterials: storage.currentMaterials || [],
            },

            timeMetrics: {
                ...timeMetrics,
                idleTime: storage.idleTime || 0,
                activeTime: storage.activeTime || 0,
                totalTime: (storage.idleTime || 0) + (storage.activeTime || 0),
            },

            capacityMetrics: {
                utilizationRate,
                averageOccupancy: utilizationRate,
                peakOccupancy: storage.peakOccupancy || utilizationRate,
                turnoverRate: 0,
            },

            throughput: {
                itemsPerHour: 0,
                itemsPerDay: 0,
                materialFlowRate: 0,
                capacityUtilization: utilizationRate,
                storeOperations: storage.storeOperations || 0,
                retrieveOperations: storage.retrieveOperations || 0,
                totalOperations: (storage.storeOperations || 0) + (storage.retrieveOperations || 0),
            },

            efficiency: {
                overallEffectiveness: calculateOEE(timeMetrics.uptime, utilizationRate, 100),
                availability: timeMetrics.uptime,
                performance: utilizationRate,
                quality: 100,
                spaceUtilization: utilizationRate,
            },

            quality: {
                errorRate: 0,
                errorFrequency: 0,
                successRate: 100,
                stateTransitions: [],
            },

            occupancyTrends: [],
            historicalData: [],
        };
    }, []);

    // ============================================================================
    // HUMAN ANALYSIS
    // ============================================================================

    const analyzeHuman = useCallback((human: any): HumanAnalysis => {
        const timeMetrics = calculateTimeMetrics(human.idleTime || 0, human.activeTime || 0);

        const totalTime = (human.idleTime || 0) + (human.activeTime || 0);
        const actionsCompleted = human.actionsCompleted || 0;

        return {
            assetId: human.modelUuid,
            assetName: human.modelName,
            assetType: "human",

            currentStatus: {
                isActive: human.isActive || false,
                isScheduled: human.isScheduled || false,
                currentPhase: human.currentPhase || "idle",
                state: human.state || "idle",
                speed: human.speed || 0,
                currentLoad: human.currentLoad || 0,
                currentMaterials: human.currentMaterials || [],
                currentAction: human.currentAction || null,
            },

            timeMetrics: {
                ...timeMetrics,
                idleTime: human.idleTime || 0,
                activeTime: human.activeTime || 0,
                totalTime,
                scheduledTime: totalTime,
            },

            productivityMetrics: {
                actionsCompleted,
                actionsPerHour: totalTime > 0 ? (actionsCompleted / totalTime) * 3600 : 0,
                averageActionTime: actionsCompleted > 0 ? totalTime / actionsCompleted : 0,
                distanceTraveled: human.distanceTraveled || 0,
            },

            workloadDistribution: [],

            efficiency: {
                overallEffectiveness: calculateOEE(timeMetrics.uptime, 100, 100),
                availability: timeMetrics.uptime,
                performance: 100,
                quality: 100,
                laborProductivity: totalTime > 0 ? actionsCompleted / (totalTime / 3600) : 0,
                utilizationRate: timeMetrics.utilizationRate * 100,
            },

            quality: {
                errorRate: 0,
                errorFrequency: 0,
                successRate: 100,
                stateTransitions: [],
            },

            historicalData: [],
        };
    }, []);

    // ============================================================================
    // CRANE ANALYSIS
    // ============================================================================

    const analyzeCrane = useCallback((crane: any): CraneAnalysis => {
        const timeMetrics = calculateTimeMetrics(crane.idleTime || 0, crane.activeTime || 0);

        const totalTime = (crane.idleTime || 0) + (crane.activeTime || 0);
        const cyclesCompleted = crane.cyclesCompleted || 0;

        return {
            assetId: crane.modelUuid,
            assetName: crane.modelName,
            assetType: "crane",

            currentStatus: {
                isActive: crane.isActive || false,
                isScheduled: crane.isScheduled || false,
                isCarrying: crane.isCarrying || false,
                currentPhase: crane.currentPhase || "idle",
                state: crane.state || "idle",
                currentLoad: crane.currentLoad || 0,
                currentMaterials: crane.currentMaterials || [],
                currentAction: crane.currentAction || null,
            },

            timeMetrics: {
                ...timeMetrics,
                idleTime: crane.idleTime || 0,
                activeTime: crane.activeTime || 0,
                totalTime,
                averageCycleTime: cyclesCompleted > 0 ? totalTime / cyclesCompleted : 0,
            },

            throughput: {
                itemsPerHour: totalTime > 0 ? (cyclesCompleted / totalTime) * 3600 : 0,
                itemsPerDay: totalTime > 0 ? (cyclesCompleted / totalTime) * 86400 : 0,
                materialFlowRate: 1,
                capacityUtilization: timeMetrics.utilizationRate * 100,
                cyclesCompleted,
                loadsHandled: crane.loadsHandled || 0,
                averageLoadsPerCycle: cyclesCompleted > 0 ? (crane.loadsHandled || 0) / cyclesCompleted : 0,
            },

            movementMetrics: {
                totalLifts: crane.totalLifts || 0,
                averageLiftHeight: crane.averageLiftHeight || 0,
                movementEfficiency: 100,
            },

            efficiency: {
                overallEffectiveness: calculateOEE(timeMetrics.uptime, 100, 100),
                availability: timeMetrics.uptime,
                performance: 100,
                quality: 100,
                loadUtilization: 0,
                cycleTimeEfficiency: 100,
            },

            quality: {
                errorRate: 0,
                errorFrequency: 0,
                successRate: 100,
                stateTransitions: [],
                liftSuccessRate: 100,
                positioningAccuracy: 100,
            },

            historicalData: [],
        };
    }, []);

    // ============================================================================
    // SYSTEM-WIDE ANALYSIS
    // ============================================================================

    const analyzeSystem = useCallback((allAssets: AssetAnalysis[]): AnalysisSchema => {
        // Calculate system-wide metrics
        const totalAssets = allAssets.length;
        const activeAssets = allAssets.filter((a) => a.currentStatus.isActive).length;
        const assetsInError = allAssets.filter((a) => a.currentStatus.state === "error").length;

        const avgOEE = allAssets.reduce((sum, a) => sum + a.efficiency.overallEffectiveness, 0) / totalAssets;
        const avgUtilization = allAssets.reduce((sum, a) => sum + a.timeMetrics.utilizationRate, 0) / totalAssets;
        const avgIdleTime = allAssets.reduce((sum, a) => sum + a.timeMetrics.idleTime, 0) / totalAssets;
        const totalDowntime = allAssets.reduce((sum, a) => sum + a.timeMetrics.downtime, 0);

        // Helper to get throughput safely
        const getThroughput = (asset: AssetAnalysis): number => {
            if ("throughput" in asset) {
                return asset.throughput.itemsPerHour;
            } else if ("productivityMetrics" in asset) {
                return asset.productivityMetrics.actionsPerHour;
            }
            return 0;
        };

        // Group by asset type
        const assetTypeGroups = allAssets.reduce((acc, asset) => {
            if (!acc[asset.assetType]) {
                acc[asset.assetType] = [];
            }
            acc[asset.assetType].push(asset);
            return acc;
        }, {} as Record<string, AssetAnalysis[]>);

        const assetTypePerformance = Object.entries(assetTypeGroups).map(([type, assets]) => ({
            assetType: type,
            count: assets.length,
            averageOEE: assets.reduce((sum, a) => sum + a.efficiency.overallEffectiveness, 0) / assets.length,
            averageUtilization: (assets.reduce((sum, a) => sum + a.timeMetrics.utilizationRate, 0) / assets.length) * 100,
            totalThroughput: assets.reduce((sum, a) => sum + getThroughput(a), 0),
        }));

        // Identify bottlenecks (high utilization + low throughput)
        const bottlenecks = allAssets
            .filter((a) => a.timeMetrics.utilizationRate > 0.8)
            .map((a) => ({
                assetId: a.assetId,
                assetName: a.assetName,
                severity:
                    a.timeMetrics.utilizationRate > 0.95
                        ? ("critical" as const)
                        : a.timeMetrics.utilizationRate > 0.9
                        ? ("high" as const)
                        : a.timeMetrics.utilizationRate > 0.85
                        ? ("medium" as const)
                        : ("low" as const),
                utilizationRate: a.timeMetrics.utilizationRate * 100,
                queueLength: 0,
                impactScore: a.timeMetrics.utilizationRate * 100,
            }))
            .sort((a, b) => b.impactScore - a.impactScore);

        return {
            assets: allAssets,

            systemPerformance: {
                overallOEE: avgOEE,
                systemThroughput: allAssets.reduce((sum, a) => sum + getThroughput(a), 0),
                systemUtilization: avgUtilization * 100,
                assetTypePerformance,
                criticalMetrics: {
                    activeAssets,
                    totalAssets,
                    assetsInError,
                    averageIdleTime: avgIdleTime,
                    totalDowntime,
                },
            },

            materialFlow: {
                totalMaterialsInSystem: 0,
                materialsCompleted: 0,
                averageResidenceTime: 0,
                queueLengths: [],
                bottlenecks,
                flowContinuity: {
                    overallFlowRate: 0,
                    varianceCoefficient: 0,
                    steadyStateDeviation: 0,
                },
            },

            predictiveInsights: {
                maintenanceAlerts: [],
                optimizationOpportunities: [],
                trendAnalysis: [],
            },

            analysisTimeRange: {
                startTime: startTimeRef.current,
                endTime: new Date().toISOString(),
                duration: Date.now() - new Date(startTimeRef.current).getTime(),
            },

            metadata: {
                lastUpdated: new Date().toISOString(),
                dataPoints: allAssets.length,
                analysisVersion: "1.0.0",
            },
        };
    }, []);

    // ============================================================================
    // MAIN ANALYSIS FUNCTION
    // ============================================================================

    const performAnalysis = useCallback(() => {
        setAnalyzing(true);

        try {
            const allAssets: AssetAnalysis[] = [];

            // Analyze all conveyors
            conveyors.forEach((conveyor) => {
                allAssets.push(analyzeConveyor(conveyor));
            });

            // Analyze all vehicles
            vehicles.forEach((vehicle) => {
                allAssets.push(analyzeVehicle(vehicle));
            });

            // Analyze all robotic arms
            armBots.forEach((armBot) => {
                allAssets.push(analyzeRoboticArm(armBot));
            });

            // Analyze all machines
            machines.forEach((machine) => {
                allAssets.push(analyzeMachine(machine));
            });

            // Analyze all storage units
            storageUnits.forEach((storage) => {
                allAssets.push(analyzeStorage(storage));
            });

            // Analyze all humans
            humans.forEach((human) => {
                allAssets.push(analyzeHuman(human));
            });

            // Analyze all cranes
            cranes.forEach((crane) => {
                allAssets.push(analyzeCrane(crane));
            });

            // Perform system-wide analysis
            const completeAnalysis = analyzeSystem(allAssets);

            setAnalysis(completeAnalysis);
        } catch (error) {
            console.error("Analysis error:", error);
        } finally {
            setAnalyzing(false);
        }
    }, [
        conveyors,
        vehicles,
        armBots,
        machines,
        humans,
        cranes,
        analyzeConveyor,
        analyzeVehicle,
        analyzeRoboticArm,
        analyzeMachine,
        analyzeHuman,
        analyzeCrane,
        analyzeSystem,
        setAnalysis,
        setAnalyzing,
    ]);

    // ============================================================================
    // EFFECTS
    // ============================================================================

    // Perform initial analysis and set up interval
    useEffect(() => {
        if (!isPlaying) return;
        // Initial analysis
        performAnalysis();

        // Set up periodic analysis (every 5 seconds)
        analysisIntervalRef.current = setInterval(() => {
            performAnalysis();
        }, 5000);

        return () => {
            if (analysisIntervalRef.current) {
                clearInterval(analysisIntervalRef.current);
            }
        };
    }, [performAnalysis, isPlaying]);

    return null;
}

export default Analyzer;
