import { useCallback, useEffect, useRef } from "react";
import * as THREE from 'three';
import { useFrame } from "@react-three/fiber";
import { useMaterialStore } from "../../../../../store/simulation/useMaterialStore";
import { useProductStore } from "../../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";

export function useSpawnHandler() {
    const { addMaterial } = useMaterialStore();
    const { getModelUuidByActionUuid, getPointUuidByActionUuid } = useProductStore();
    const { selectedProduct } = useSelectedProduct();
    const lastSpawnTime = useRef<number | null>(null);
    const startTime = useRef<number | null>(null);
    const spawnCountRef = useRef<number>(0);
    const spawnParams = useRef<{
        material: string;
        intervalMs: number;
        totalCount: number;
        action: ConveyorAction;
    } | null>(null);

    const clearCurrentSpawn = useCallback(() => {
        lastSpawnTime.current = null;
        startTime.current = null;
        spawnCountRef.current = 0;
        spawnParams.current = null;
    }, []);

    const spawnLogStatus = (materialUuid: string, status: string) => {
        // console.log(`${materialUuid}, ${status}`);
    }

    const createNewMaterial = useCallback((materialType: string, action: ConveyorAction) => {
        const modelUuid = getModelUuidByActionUuid(selectedProduct.productId, action.actionUuid);
        const pointUuid = getPointUuidByActionUuid(selectedProduct.productId, action.actionUuid);
        if (!modelUuid || !pointUuid) return;

        const newMaterial: MaterialSchema = {
            materialId: THREE.MathUtils.generateUUID(),
            materialName: `${materialType}-${Date.now()}`,
            materialType: materialType,
            isActive: false,
            isVisible: true,
            isRendered: true,
            current: {
                modelUuid: modelUuid,
                pointUuid: pointUuid,
                actionUuid: action?.actionUuid || ''
            },
            weight: 1,
            cost: 1
        };

        if (action.triggers[0].triggeredAsset?.triggeredModel.modelUuid &&
            action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid &&
            action.triggers[0].triggeredAsset?.triggeredAction?.actionUuid
        ) {
            newMaterial.next = {
                modelUuid: action.triggers[0].triggeredAsset?.triggeredModel.modelUuid,
                pointUuid: action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid,
                actionUuid: action.triggers[0].triggeredAsset?.triggeredAction?.actionUuid
            }
        }

        addMaterial(newMaterial);
        return newMaterial;
    }, [addMaterial]);

    useFrame(() => {
        if (!spawnParams.current || !startTime.current) return;

        const currentTime = performance.now();
        const { material, intervalMs, totalCount, action } = spawnParams.current;
        const isFirstSpawn = lastSpawnTime.current === null;
        const elapsed = currentTime - startTime.current;

        // First spawn
        if (isFirstSpawn) {
            if (elapsed >= intervalMs) {
                const createdMaterial = createNewMaterial(material, action);
                if (createdMaterial) {
                    spawnLogStatus(createdMaterial.materialId, `[${elapsed.toFixed(2)}ms] Spawned ${material} (1/${totalCount})`);
                }
                lastSpawnTime.current = currentTime;
                spawnCountRef.current = 1;

                if (totalCount <= 1) {
                    clearCurrentSpawn();
                }
            }
            return;
        }

        // Subsequent spawns
        if (lastSpawnTime.current !== null) {
            const timeSinceLast = currentTime - lastSpawnTime.current;
            if (timeSinceLast >= intervalMs) {
                const count = spawnCountRef.current + 1;
                const createdMaterial = createNewMaterial(material, action);
                if (createdMaterial) {
                    spawnLogStatus(createdMaterial.materialId, `[${elapsed.toFixed(2)}ms] Spawned ${material} (${count}/${totalCount})`);
                }
                lastSpawnTime.current = currentTime;
                spawnCountRef.current = count;

                if (count >= totalCount) {
                    clearCurrentSpawn();
                }
            }
        }
    });

    const handleSpawn = useCallback((action: ConveyorAction) => {
        if (!action || action.actionType !== 'spawn') return;

        const { material, spawnInterval = 0, spawnCount = 1 } = action;
        const intervalMs = spawnInterval * 1000;

        clearCurrentSpawn();

        spawnParams.current = {
            material,
            intervalMs,
            totalCount: spawnCount,
            action: action
        };

        startTime.current = performance.now();
    }, [clearCurrentSpawn]);

    useEffect(() => {
        return () => {
            clearCurrentSpawn();
        };
    }, [clearCurrentSpawn]);

    return {
        handleSpawn,
        clearCurrentSpawn
    };
}