import { useEffect, useMemo } from "react";
import { Object3D, Box3, Vector3 } from "three";
import { useThree } from "@react-three/fiber";
import { useLoadingProgress } from "../../../../../store/builder/store";
import { MaterialModel } from "../../../materials/instances/material/materialModel";
import { useSceneContext } from "../../../../scene/sceneContext";

const MaterialAnimator = ({
    storage,
}: Readonly<{ storage: StorageUnitStatus }>) => {
    const { scene } = useThree();
    const padding = 0.1;
    const { loadingProgress } = useLoadingProgress();
    const { materialStore } = useSceneContext();
    const { materialPositions, setMaterialPositions } = materialStore();

    const storageModel = useMemo(() => {
        return scene.getObjectByProperty("uuid", storage.modelUuid) as Object3D;
    }, [scene, storage.modelUuid, loadingProgress]);

    useEffect(() => {
        if (!storageModel || storage.currentMaterials.length === 0) {
            setMaterialPositions(storage.modelUuid, []);
            return;
        }

        const box = new Box3().setFromObject(storageModel);
        const size = new Vector3();
        box.getSize(size);

        const materialWidth = 0.45;
        const materialDepth = 0.45;
        const materialHeight = 0.3;
        const cols = Math.floor(size.x / materialWidth);
        const rows = Math.floor(size.z / materialDepth);
        const itemsPerLayer = cols * rows;

        const origin = new Vector3(
            box.min.x + materialWidth / 2,
            box.max.y + padding,
            box.min.z + materialDepth / 2
        );

        const newMaterials = storage.currentMaterials.map((mat, i) => {
            const layer = Math.floor(i / itemsPerLayer);
            const layerIndex = i % itemsPerLayer;
            const row = Math.floor(layerIndex / cols);
            const col = layerIndex % cols;

            const position = new Vector3(
                origin.x + col * materialWidth,
                origin.y + layer * (materialHeight + padding),
                origin.z + row * materialDepth
            );

            return {
                materialId: mat.materialId,
                position,
            };
        });

        setMaterialPositions(storage.modelUuid, newMaterials);
    }, [storageModel, storage.currentMaterials]);

    return (
        <group position={[0, -padding, 0]}>
            {(materialPositions[storage.modelUuid] || []).map(({ materialId, position }) => {
                const mat = storage.currentMaterials.find((m) => m.materialId === materialId);
                return (
                    <MaterialModel
                        key={materialId}
                        materialId={materialId}
                        matRef={null}
                        materialType={mat?.materialType ?? "Default material"}
                        position={position}
                    />
                );
            })}
        </group>
    );

};

export default MaterialAnimator;
