import * as THREE from "three"
import { useEffect } from 'react'
import { getFloorAssets } from '../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi';
import { useLoadingProgress } from '../../../store/builder/store';
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { FloorItems } from "../../../types/world/worldTypes";
import { useAssetsStore } from "../../../store/builder/useAssetStore";
import Models from "./models/models";
import { useGLTF } from "@react-three/drei";

const gltfLoaderWorker = new Worker(
    new URL(
        "../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js",
        import.meta.url
    )
);

function AssetsGroup() {
    const { setLoadingProgress } = useLoadingProgress();
    const { setAssets } = useAssetsStore();

    const loader = new GLTFLoader();
    const dracoLoader = new DRACOLoader();

    dracoLoader.setDecoderPath(
        "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/"
    );
    loader.setDRACOLoader(dracoLoader);

    useEffect(() => {
        const email = localStorage.getItem("email");
        const organization = email!.split("@")[1].split(".")[0];

        let totalAssets = 0;
        let loadedAssets = 0;

        const updateLoadingProgress = (progress: number) => {
            if (progress < 100) {
                setLoadingProgress(progress);
            } else if (progress === 100) {
                setTimeout(() => {
                    setLoadingProgress(100);
                    setTimeout(() => {
                        setLoadingProgress(0);
                    }, 1500);
                }, 1000);
            }
        };

        getFloorAssets(organization).then((data) => {
            if (data.length > 0) {
                const uniqueItems = (data as FloorItems).filter((item, index, self) => index === self.findIndex((t) => t.modelfileID === item.modelfileID));
                totalAssets = uniqueItems.length;
                if (totalAssets === 0) {
                    updateLoadingProgress(100);
                    return;
                }
                gltfLoaderWorker.postMessage({ floorItems: uniqueItems });
            } else {
                gltfLoaderWorker.postMessage({ floorItems: [] });
                updateLoadingProgress(100);
            }
        });

        gltfLoaderWorker.onmessage = async (event) => {
            if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
                const blobUrl = URL.createObjectURL(event.data.modelBlob);
                loader.load(blobUrl, (gltf) => {
                    URL.revokeObjectURL(blobUrl);
                    THREE.Cache.remove(blobUrl);
                    THREE.Cache.add(event.data.modelID, gltf);

                    loadedAssets++;
                    const progress = Math.round((loadedAssets / totalAssets) * 100);
                    updateLoadingProgress(progress);

                    if (loadedAssets === totalAssets) {
                        const assets: Asset[] = [];
                        getFloorAssets(organization).then((data: FloorItems) => {
                            data.forEach((item) => {
                                if (item.eventData) {
                                    assets.push({
                                        modelUuid: item.modelUuid,
                                        modelName: item.modelName,
                                        assetId: item.modelfileID,
                                        position: item.position,
                                        rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
                                        isLocked: item.isLocked,
                                        isCollidable: false,
                                        isVisible: item.isVisible,
                                        opacity: 1,
                                        eventData: item.eventData
                                    })
                                } else {
                                    assets.push({
                                        modelUuid: item.modelUuid,
                                        modelName: item.modelName,
                                        assetId: item.modelfileID,
                                        position: item.position,
                                        rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
                                        isLocked: item.isLocked,
                                        isCollidable: false,
                                        isVisible: item.isVisible,
                                        opacity: 1,
                                    })
                                }
                            })
                            setAssets(assets);
                        })
                        updateLoadingProgress(100);
                    }
                });
            }
        };
    }, []);

    return (
        <>
            <Models />
        </>
    )
}

export default AssetsGroup;