import { useEffect } from "react";
import * as THREE from "three";
import gsap from "gsap";
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import {
    useSocketStore,
    useActiveLayer,
    useWallItems,
    useLayers,
    useUpdateScene,
    useWalls,
    useDeletedLines,
    useNewLines,
    useZonePoints,
    useZones,
} from "../../../store/builder/store";

import * as Types from "../../../types/world/worldTypes";
import * as CONSTANTS from "../../../types/world/worldConstants";

// import { setFloorItemApi } from "../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
import objectLineToArray from "../../builder/geomentries/lines/lineConvertions/objectLineToArray";
import addLineToScene from "../../builder/geomentries/lines/addLineToScene";
import updateLinesPositions from "../../builder/geomentries/lines/updateLinesPositions";
import updateLines from "../../builder/geomentries/lines/updateLines";
import updateDistanceText from "../../builder/geomentries/lines/updateDistanceText";
import updateFloorLines from "../../builder/geomentries/floors/updateFloorLines";
import loadWalls from "../../builder/geomentries/walls/loadWalls";
import RemoveConnectedLines from "../../builder/geomentries/lines/removeConnectedLines";
import Layer2DVisibility from "../../builder/geomentries/layers/layer2DVisibility";
import { retrieveGLTF, storeGLTF } from "../../../utils/indexDB/idbUtils";
import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi";
import { useParams } from "react-router-dom";
import { useEventsStore } from "../../../store/simulation/useEventsStore";
import { useProductStore } from "../../../store/simulation/useProductStore";
import { getUserData } from "../../../functions/getUserData";
import { useSceneContext } from "../../scene/sceneContext";
import { useVersionContext } from "../../builder/version/versionContext";

export default function SocketResponses({
    floorPlanGroup,
    lines,
    floorGroup,
    scene,
    onlyFloorlines,
    currentLayerPoint,
    floorPlanGroupPoint,
    floorPlanGroupLine,
    dragPointControls,
}: any) {
    const { socket } = useSocketStore();
    const { activeLayer, setActiveLayer } = useActiveLayer();
    const { wallItems, setWallItems } = useWallItems();
    const { setLayers } = useLayers();
    const { setUpdateScene } = useUpdateScene();
    const { setWalls } = useWalls();
    const { setDeletedLines } = useDeletedLines();
    const { setNewLines } = useNewLines();
    const { zones, setZones } = useZones();
    const { zonePoints, setZonePoints } = useZonePoints();
    const { selectedVersionStore } = useVersionContext();
    const { selectedVersion } = selectedVersionStore();
    const { projectId } = useParams();
    const { assetStore } = useSceneContext();
    const { addAsset, updateAsset, removeAsset } = assetStore();
    const { organization } = getUserData();

    useEffect(() => {

        if (!socket) return;

        socket.on("cameraCreateResponse", (data: any) => {
            // 
        });

        socket.on("userConnectRespones", (data: any) => {
            // 
        });

        socket.on("userDisConnectRespones", (data: any) => {
            // 
        });

        socket.on("v1:camera:Response:update", (data: any) => {
            // 
        });

        socket.on("EnvironmentUpdateResponse", (data: any) => {
            // 
        });

        socket.on("v1:model-asset:response:add", async (data: any) => {
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }
            if (data.message === "Model created successfully") {
                try {

                    const asset: Asset = {
                        modelUuid: data.data.modelUuid,
                        modelName: data.data.modelName,
                        assetId: data.data.assetId,
                        position: data.data.position,
                        rotation: [data.data.rotation.x, data.data.rotation.y, data.data.rotation.z],
                        isLocked: data.data.isLocked,
                        isCollidable: false,
                        isVisible: data.data.isVisible,
                        opacity: 1,
                    }

                    addAsset(asset);

                    echo.success("Added model through collaboration");
                } catch (error) {
                    echo.error("Failed to create model through collaboration");
                }
            } else if (data.message === "Model updated successfully") {
                try {

                    const asset: Asset = {
                        modelUuid: data.data.modelUuid,
                        modelName: data.data.modelName,
                        assetId: data.data.assetId,
                        position: data.data.position,
                        rotation: [data.data.rotation.x, data.data.rotation.y, data.data.rotation.z],
                        isLocked: data.data.isLocked,
                        isCollidable: false,
                        isVisible: data.data.isVisible,
                        opacity: 1,
                    }

                    updateAsset(asset.modelUuid, {
                        position: asset.position,
                        rotation: asset.rotation,
                    });

                    echo.success("Updated model through collaboration");
                } catch (error) {
                    echo.error("Failed to update model through collaboration");
                }
            } else {
                echo.error("Failed executing action from collaboration");
            }
        });

        socket.on("v1:model-asset:response:delete", (data: any) => {
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }
            if (data.message === "Model deleted successfully") {
                try {
                    const deletedUUID = data.data.modelUuid;

                    useEventsStore.getState().removeEvent(deletedUUID);
                    useProductStore.getState().deleteEvent(deletedUUID);

                    removeAsset(deletedUUID);

                    echo.success("Model Removed successfully through collaboration");
                } catch (error) {
                    echo.error("Failed to remove model through collaboration");
                }
            }
        });

        socket.on("v1:Line:response:update", (data: any) => {
            // console.log('data: ', data);
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }
            if (data.message === "line updated") {
                const DraggedUUID = data.data.uuid;
                const DraggedPosition = new THREE.Vector3(
                    data.data.position.x,
                    data.data.position.y,
                    data.data.position.z
                );

                const point = floorPlanGroupPoint.current.getObjectByProperty(
                    "uuid",
                    DraggedUUID
                );
                point.position.set(
                    DraggedPosition.x,
                    DraggedPosition.y,
                    DraggedPosition.z
                );
                const affectedLines = updateLinesPositions(
                    { uuid: DraggedUUID, position: DraggedPosition },
                    lines
                );

                updateLines(floorPlanGroupLine, affectedLines);
                updateDistanceText(scene, floorPlanGroupLine, affectedLines);
                updateFloorLines(onlyFloorlines, {
                    uuid: DraggedUUID,
                    position: DraggedPosition,
                });

                loadWalls(lines, setWalls);
                setUpdateScene(true);
            }
        });

        socket.on("v1:Line:response:delete", (data: any) => {
            // console.log('data: ', data);
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }
            if (data.message === "line deleted") {
                const line = objectLineToArray(data.data);
                const linePoints = line;
                const connectedpoints = [linePoints[0][1], linePoints[1][1]];

                onlyFloorlines.current = onlyFloorlines.current
                    .map((floorline: any) =>
                        floorline.filter(
                            (line: any) =>
                                line[0][1] !== connectedpoints[0] &&
                                line[1][1] !== connectedpoints[1]
                        )
                    )
                    .filter((floorline: any) => floorline.length > 0);

                const removedLine = lines.current.find(
                    (item: any) =>
                        (item[0][1] === linePoints[0][1] &&
                            item[1][1] === linePoints[1][1]) ||
                        (item[0][1] === linePoints[1][1] && item[1][1] === linePoints[0][1])
                );
                lines.current = lines.current.filter(
                    (item: any) => item !== removedLine
                );

                floorPlanGroupLine.current.children.forEach((line: any) => {
                    const linePoints = line.userData.linePoints as [
                        number,
                        string,
                        number
                    ][];
                    const uuid1 = linePoints[0][1];
                    const uuid2 = linePoints[1][1];

                    if (
                        (uuid1 === connectedpoints[0] && uuid2 === connectedpoints[1]) ||
                        (uuid1 === connectedpoints[1] && uuid2 === connectedpoints[0])
                    ) {
                        line.material.dispose();
                        line.geometry.dispose();
                        floorPlanGroupLine.current.remove(line);
                        setDeletedLines([line.userData.linePoints]);
                    }
                });

                connectedpoints.forEach((pointUUID) => {
                    let isConnected = false;
                    floorPlanGroupLine.current.children.forEach((line: any) => {
                        const linePoints = line.userData.linePoints;
                        const uuid1 = linePoints[0][1];
                        const uuid2 = linePoints[1][1];
                        if (uuid1 === pointUUID || uuid2 === pointUUID) {
                            isConnected = true;
                        }
                    });

                    if (!isConnected) {
                        floorPlanGroupPoint.current.children.forEach((point: any) => {
                            if (point.uuid === pointUUID) {
                                point.material.dispose();
                                point.geometry.dispose();
                                floorPlanGroupPoint.current.remove(point);
                            }
                        });
                    }
                });

                loadWalls(lines, setWalls);
                setUpdateScene(true);

                echo.success("Line Removed!");
            }
        });

        socket.on("v1:Line:response:delete:point", (data: any) => {
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }
            if (data.message === "point deleted") {
                const point = floorPlanGroupPoint.current?.getObjectByProperty(
                    "uuid",
                    data.data
                );
                point.material.dispose();
                point.geometry.dispose();
                floorPlanGroupPoint.current.remove(point);

                onlyFloorlines.current = onlyFloorlines.current
                    .map((floorline: any) =>
                        floorline.filter(
                            (line: any) =>
                                line[0][1] !== data.data && line[1][1] !== data.data
                        )
                    )
                    .filter((floorline: any) => floorline.length > 0);

                RemoveConnectedLines(
                    data.data,
                    floorPlanGroupLine,
                    floorPlanGroupPoint,
                    setDeletedLines,
                    lines
                );

                loadWalls(lines, setWalls);
                setUpdateScene(true);

                echo.success("Point Removed!");
            }
        });

        socket.on("v1:Line:response:delete:layer", async (data: any) => {
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }
            if (data.message === "layer deleted") {
                setActiveLayer(1);
                const removedLayer = data.data;
                const removedLines: Types.Lines = lines.current.filter(
                    (line: any) => line[0][2] === removedLayer
                );

                //////////  Remove Points and lines from the removed layer  //////////

                removedLines.forEach(async (line) => {
                    line.forEach(async (removedPoint) => {
                        const removableLines: THREE.Mesh[] = [];
                        const connectedpoints: string[] = [];

                        floorPlanGroupLine.current.children.forEach((line: any) => {
                            const linePoints = line.userData.linePoints as [
                                number,
                                string,
                                number
                            ][];
                            const uuid1 = linePoints[0][1];
                            const uuid2 = linePoints[1][1];

                            if (uuid1 === removedPoint[1] || uuid2 === removedPoint[1]) {
                                connectedpoints.push(uuid1 === removedPoint[1] ? uuid2 : uuid1);
                                removableLines.push(line as THREE.Mesh);
                            }
                        });

                        if (removableLines.length > 0) {
                            removableLines.forEach((line: any) => {
                                lines.current = lines.current.filter(
                                    (item: any) =>
                                        JSON.stringify(item) !==
                                        JSON.stringify(line.userData.linePoints)
                                );
                                line.material.dispose();
                                line.geometry.dispose();
                                floorPlanGroupLine.current.remove(line);
                            });
                        }

                        const point = floorPlanGroupPoint.current.getObjectByProperty(
                            "uuid",
                            removedPoint[1]
                        );
                        if (point) {
                            point.material.dispose();
                            point.geometry.dispose();
                            floorPlanGroupPoint.current.remove(point);
                        }
                    });
                });

                //////////  Update the remaining lines layer values in the userData and in lines.current  //////////

                let remaining = lines.current.filter(
                    (line: any) => line[0][2] !== removedLayer
                );
                let updatedLines: Types.Lines = [];
                remaining.forEach((line: any) => {
                    let newLines = JSON.parse(JSON.stringify(line));
                    if (newLines[0][2] > removedLayer) {
                        newLines[0][2] -= 1;
                        newLines[1][2] -= 1;
                    }

                    const matchingLine = floorPlanGroupLine.current.children.find(
                        (l: any) =>
                            l.userData.linePoints[0][1] === line[0][1] &&
                            l.userData.linePoints[1][1] === line[1][1]
                    );
                    if (matchingLine) {
                        const updatedUserData = JSON.parse(
                            JSON.stringify(matchingLine.userData)
                        );
                        updatedUserData.linePoints[0][2] = newLines[0][2];
                        updatedUserData.linePoints[1][2] = newLines[1][2];
                        matchingLine.userData = updatedUserData;
                    }
                    updatedLines.push(newLines);
                });

                lines.current = updatedLines;
                localStorage.setItem("Lines", JSON.stringify(lines.current));

                //////////  Also remove OnlyFloorLines and update it in localstorage  //////////

                onlyFloorlines.current = onlyFloorlines.current.filter((floor: any) => {
                    return floor[0][0][2] !== removedLayer;
                });
                const meshToRemove = floorGroup.current?.children.find(
                    (mesh: any) => mesh.name === `Only_Floor_Line_${removedLayer}`
                );
                if (meshToRemove) {
                    meshToRemove.geometry.dispose();
                    meshToRemove.material.dispose();
                    floorGroup.current?.remove(meshToRemove);
                }

                const zonesData = await getZonesApi(organization, projectId, selectedVersion?.versionId || '');
                const highestLayer = Math.max(
                    1,
                    lines.current.reduce(
                        (maxLayer: number, segment: any) =>
                            Math.max(maxLayer, segment.layer || 0),
                        0
                    ),
                    zonesData.reduce(
                        (maxLayer: number, zone: any) =>
                            Math.max(maxLayer, zone.layer || 0),
                        0
                    )
                );

                setLayers(highestLayer);

                loadWalls(lines, setWalls);
                setUpdateScene(true);

                echo.success("Layer Removed!");
            }
        });

        return () => {
            socket.off("cameraCreateResponse");
            socket.off("userConnectRespones");
            socket.off("userDisConnectRespones");
            socket.off("v1:camera:Response:update");
            socket.off("EnvironmentUpdateResponse");
            socket.off("v1:model-asset:response:add");
            socket.off("v1:model-asset:response:delete");
            socket.off("v1:Line:response:update");
            socket.off("v1:Line:response:delete");
            socket.off("v1:Line:response:delete:point");
            socket.off("v1:Line:response:delete:layer");
        }
    }, [socket, selectedVersion?.versionId]);

    useEffect(() => {
        if (!socket) return;
        let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;

        socket.on("v1:wallItem:Response:Delete", (data: any) => {
            // console.log('data: ', data);
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }
            if (data.message === "wall Item deleted successfully") {
                const deletedUUID = data.data.modelUuid;
                let WallItemsRef = wallItems;
                const Items = WallItemsRef.filter((item: any) => item.model?.uuid !== deletedUUID);

                setWallItems([]);
                setTimeout(async () => {
                    WallItemsRef = Items;
                    setWallItems(WallItemsRef);
                    const WallItemsForStorage = WallItemsRef.map((item: any) => {
                        const { model, ...rest } = item;
                        return {
                            ...rest,
                            modelUuid: model?.uuid,
                        };
                    });

                    localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage));
                    echo.success("Model Removed!");
                }, 50);
            }
        });

        socket.on("v1:wallItems:Response:Update", (data: any) => {
            // console.log('data: ', data);
            // 
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }
            if (data.message === "wall Item created successfully") {
                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);

                // Check THREE.js cache first
                const cachedModel = THREE.Cache.get(data.data.assetId);
                if (cachedModel) {
                    handleModelLoad(cachedModel);
                    return;
                }

                // Check IndexedDB cache
                retrieveGLTF(data.data.assetId).then((cachedModelBlob) => {
                    if (cachedModelBlob) {
                        const blobUrl = URL.createObjectURL(cachedModelBlob);
                        loader.load(blobUrl, (gltf) => {
                            URL.revokeObjectURL(blobUrl);
                            THREE.Cache.remove(blobUrl);
                            THREE.Cache.add(data.data.assetId, gltf);
                            handleModelLoad(gltf);
                        });
                        return;
                    }
                })

                // Load from backend if not in any cache
                loader.load(`${url_Backend_dwinzo}/api/v2/AssetFile/${data.data.assetId}`, async (gltf) => {
                    try {
                        const modelBlob = await fetch(`${url_Backend_dwinzo}/api/v2/AssetFile/${data.data.assetId}`).then((res) => res.blob());
                        await storeGLTF(data.data.assetId, modelBlob);
                        THREE.Cache.add(data.data.assetId, gltf);
                        await handleModelLoad(gltf);
                    } catch (error) {

                        handleModelLoad(gltf);
                    }
                });

                async function handleModelLoad(gltf: GLTF) {
                    const model = gltf.scene.clone();
                    model.uuid = data.data.modelUuid;

                    model.children[0].children.forEach((child) => {
                        if (child.name !== "CSG_REF") {
                            child.castShadow = true;
                            child.receiveShadow = true;
                        }
                    });

                    const newWallItem = {
                        type: data.data.type,
                        model: model,
                        modelName: data.data.modelName,
                        assetId: data.data.assetId,
                        scale: data.data.scale,
                        csgscale: data.data.csgscale,
                        csgposition: data.data.csgposition,
                        position: data.data.position,
                        quaternion: data.data.quaternion,
                    };

                    setWallItems((prevItems: Types.wallItems) => {
                        const updatedItems = [...prevItems, newWallItem];

                        const WallItemsForStorage = updatedItems.map(item => {
                            const { model, ...rest } = item;
                            return {
                                ...rest,
                                modelUuid: model?.uuid,
                            };
                        });

                        localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage));
                        echo.success("Model Added!");
                        return updatedItems;
                    });
                }

            } else if (data.message === "Updated successfully") {
                const updatedUUID = data.data.modelUuid;

                setWallItems((prevItems: any) => {
                    const updatedItems = prevItems.map((item: any) => {
                        if (item.model.uuid === updatedUUID) {
                            return {
                                ...item,
                                position: data.data.position,
                                quaternion: data.data.quaternion,
                                scale: data.data.scale,
                                csgscale: data.data.csgscale,
                                csgposition: data.data.csgposition,
                            };
                        }
                        return item;
                    });

                    const WallItemsForStorage = updatedItems.map((item: any) => {
                        const { model, ...rest } = item;
                        return {
                            ...rest,
                            modelUuid: model?.uuid,
                        };
                    });

                    localStorage.setItem(
                        "WallItems",
                        JSON.stringify(WallItemsForStorage)
                    );
                    echo.success("Model Updated!");

                    return updatedItems;
                });
            }
        });

        return () => {
            socket.off("v1:wallItem:Response:Delete");
            socket.off("v1:wallItems:Response:Update");
        };
    }, [socket, wallItems]);

    function getPointColor(lineType: string | undefined): string {
        switch (lineType) {
            case CONSTANTS.lineConfig.wallName:
                return CONSTANTS.pointConfig.wallOuterColor;
            case CONSTANTS.lineConfig.floorName:
                return CONSTANTS.pointConfig.floorOuterColor;
            case CONSTANTS.lineConfig.aisleName:
                return CONSTANTS.pointConfig.aisleOuterColor;
            default:
                return CONSTANTS.pointConfig.defaultOuterColor;
        }
    }

    function getLineColor(lineType: string | undefined): string {
        switch (lineType) {
            case CONSTANTS.lineConfig.wallName:
                return CONSTANTS.lineConfig.wallColor;
            case CONSTANTS.lineConfig.floorName:
                return CONSTANTS.lineConfig.floorColor;
            case CONSTANTS.lineConfig.aisleName:
                return CONSTANTS.lineConfig.aisleColor;
            default:
                return CONSTANTS.lineConfig.defaultColor;
        }
    }

    useEffect(() => {
        if (!socket) return;

        socket.on("v1:Line:response:create", async (data: any) => {
            // 
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }
            if (data.message === "line create") {
                const line: Types.Line = objectLineToArray(data.data);
                const type = line[0][3];
                const pointColour = getPointColor(type);
                const lineColour = getLineColor(type);
                setNewLines([line]);

                line.forEach((line) => {
                    const existingPoint =
                        floorPlanGroupPoint.current?.getObjectByProperty("uuid", line[1]);
                    if (existingPoint) {
                        return;
                    }
                    const geometry = new THREE.BoxGeometry(
                        ...CONSTANTS.pointConfig.boxScale
                    );
                    const material = new THREE.ShaderMaterial({
                        uniforms: {
                            uOuterColor: { value: new THREE.Color(pointColour) }, // Blue color for the border
                            uInnerColor: {
                                value: new THREE.Color(CONSTANTS.pointConfig.defaultInnerColor),
                            }, // White color for the inner square
                        },
                        vertexShader: `
                                      varying vec2 vUv;
                                  
                                      void main() {
                                        vUv = uv;
                                        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
                                      }
                                    `,
                        fragmentShader: `
                                      varying vec2 vUv;
                                      uniform vec3 uOuterColor;
                                      uniform vec3 uInnerColor;
                                  
                                      void main() {
                                        // Define the size of the white square as a proportion of the face
                                        float borderThickness = 0.2; // Adjust this value for border thickness
                                        if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && 
                                            vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) {
                                          gl_FragColor = vec4(uInnerColor, 1.0); // White inner square
                                        } else {
                                          gl_FragColor = vec4(uOuterColor, 1.0); // Blue border
                                        }
                                      }
                                    `,
                    });
                    const point = new THREE.Mesh(geometry, material);
                    point.name = "point";
                    point.uuid = line[1];
                    point.userData = { type: type, color: pointColour };
                    point.position.set(line[0].x, line[0].y, line[0].z);
                    currentLayerPoint.current.push(point);

                    floorPlanGroupPoint.current?.add(point);
                });
                if (dragPointControls.current) {
                    dragPointControls.current!.objects = currentLayerPoint.current;
                }
                addLineToScene(
                    new THREE.Vector3(line[0][0].x, line[0][0].y, line[0][0].z),
                    new THREE.Vector3(line[1][0].x, line[1][0].y, line[1][0].z),
                    lineColour,
                    line,
                    floorPlanGroupLine
                );
                lines.current.push(line);

                const zonesData = await getZonesApi(organization, projectId, selectedVersion?.versionId || '');
                const highestLayer = Math.max(
                    1,
                    lines.current.reduce(
                        (maxLayer: number, segment: any) =>
                            Math.max(maxLayer, segment.layer || 0),
                        0
                    ),
                    zonesData.reduce(
                        (maxLayer: number, zone: any) =>
                            Math.max(maxLayer, zone.layer || 0),
                        0
                    )
                );

                setLayers(highestLayer);

                Layer2DVisibility(
                    activeLayer,
                    floorPlanGroup,
                    floorPlanGroupLine,
                    floorPlanGroupPoint,
                    currentLayerPoint,
                    dragPointControls
                );

                loadWalls(lines, setWalls);
                setUpdateScene(true);
            }
        });

        return () => {
            socket.off("v1:Line:response:create");
        };
    }, [socket, activeLayer, selectedVersion?.versionId]);

    useEffect(() => {
        if (!socket) return;

        socket.on("v1:zone:response:updates", (data: any) => {
            // console.log('data: ', data);
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }

            if (data.message === "zone created") {
                const pointsArray: [number, number, number][] = data.data.points;
                const vector3Array = pointsArray.map(
                    ([x, y, z]) => new THREE.Vector3(x, y, z)
                );
                const newZones = [...zones, data.data];
                setZones(newZones);
                const updatedZonePoints = [...zonePoints, ...vector3Array];
                setZonePoints(updatedZonePoints);

                const highestLayer = Math.max(
                    1,
                    lines.current.reduce(
                        (maxLayer: number, segment: any) =>
                            Math.max(maxLayer, segment.layer || 0),
                        0
                    ),
                    newZones.reduce(
                        (maxLayer: number, zone: any) =>
                            Math.max(maxLayer, zone.layer || 0),
                        0
                    )
                );

                setLayers(highestLayer);
                setUpdateScene(true);
            }

            if (data.message === "zone updated") {
                const updatedZones = zones.map((zone: any) =>
                    zone.zoneUuid === data.data.zoneUuid ? data.data : zone
                );
                setZones(updatedZones);
                setUpdateScene(true);
            }
        });

        socket.on("v1:zone:response:delete", (data: any) => {
            // console.log('data: ', data);
            if (socket.id === data.socketId) {
                return;
            }
            if (organization !== data.organization) {
                return;
            }
            if (data.message === "zone deleted") {
                const updatedZones = zones.filter(
                    (zone: any) => zone.zoneUuid !== data.data.zoneUuid
                );
                setZones(updatedZones);

                const zoneIndex = zones.findIndex(
                    (zone: any) => zone.zoneUuid === data.data.zoneUuid
                );
                if (zoneIndex !== -1) {
                    const updatedzonePoints = zonePoints.filter(
                        (_: any, index: any) =>
                            index < zoneIndex * 4 || index >= zoneIndex * 4 + 4
                    );
                    setZonePoints(updatedzonePoints);
                }

                const highestLayer = Math.max(
                    1,
                    lines.current.reduce(
                        (maxLayer: number, segment: any) =>
                            Math.max(maxLayer, segment.layer || 0),
                        0
                    ),
                    updatedZones.reduce(
                        (maxLayer: number, zone: any) =>
                            Math.max(maxLayer, zone.layer || 0),
                        0
                    )
                );

                setLayers(highestLayer);
                setUpdateScene(true);
            }
        });

        return () => {
            socket.off("v1:zone:response:updates");
            socket.off("v1:zone:response:delete");
        };
    }, [socket, zones, zonePoints]);

    return <></>;
}
