//////////  Three and React Three Fiber Imports  //////////

import * as THREE from "three";
import { useEffect, useRef } from "react";
import { useFrame, useThree } from "@react-three/fiber";
import { Geometry } from "@react-three/csg";

//////////  Zustand State Imports  //////////

import {
    useToggleView,
    useWallVisibility,
    useRoofVisibility,
    useShadows,
    useToolMode,
    useRenderDistance,
    useLimitDistance,
} from "../../store/builder/store";

//////////  3D Function Imports  //////////

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

import SocketResponses from "../collaboration/socket/socketResponses.dev";
import Ground from "../scene/environment/ground";
import { findEnvironment } from "../../services/factoryBuilder/environment/findEnvironment";

import MeasurementTool from "../scene/tools/measurementTool";
import NavMesh from "../simulation/vehicle/navMesh/navMesh";
import CalculateAreaGroup from "./groups/calculateAreaGroup";
import LayoutImage from "./layout/layoutImage";
import AssetsGroup from "./asset/assetsGroup";
import DxfFile from "./dfx/LoadBlueprint";
import AislesGroup from "./aisle/aislesGroup";
import WallGroup from "./wall/wallGroup";
import FloorGroup from "./floor/floorGroup";
import ZoneGroup from "./zone/zoneGroup";

import { useParams } from "react-router-dom";
import { useBuilderStore } from "../../store/builder/useBuilderStore";
import { getUserData } from "../../functions/getUserData";
import WallAssetGroup from "./wallAsset/wallAssetGroup";

export default function Builder() {
    const state = useThree<Types.ThreeState>();
    const plane = useRef<THREE.Mesh>(null);
    const csgRef = useRef<any>(null);

    const { toggleView } = useToggleView();
    const { setToolMode } = useToolMode();
    const { setRoofVisibility } = useRoofVisibility();
    const { setWallVisibility } = useWallVisibility();
    const { setShadows } = useShadows();
    const { setRenderDistance } = useRenderDistance();
    const { setLimitDistance } = useLimitDistance();
    const { projectId } = useParams();
    const { setHoveredPoint, setHoveredLine } = useBuilderStore();
    const { userId, organization } = getUserData();

    useEffect(() => {
        if (!toggleView) {
            setHoveredLine(null);
            setHoveredPoint(null);
            state.gl.domElement.style.cursor = 'default';
            setToolMode('cursor');
        }
    }, [toggleView]);

    useEffect(() => {

        async function fetchVisibility() {
            const data = await findEnvironment(organization, userId, projectId);
            if (data) {
                setRoofVisibility(data.roofVisibility);
                setWallVisibility(data.wallVisibility);
                setShadows(data.shadowVisibility);
                setRenderDistance(data.renderDistance);
                setLimitDistance(data.limitDistance);
            }
        }
        fetchVisibility();
    }, []);

    useFrame(() => {
        if (csgRef.current) {
            csgRef.current.update();
        }
    })

    return (
        <>
            <Ground plane={plane} />

            <SocketResponses />

            <AssetsGroup plane={plane} />

            <mesh name='Walls-And-WallAssets-Group'>
                <Geometry ref={csgRef} useGroups>

                    <WallGroup />

                    <WallAssetGroup />

                </Geometry>
            </mesh>

            <AislesGroup />

            <FloorGroup />

            <ZoneGroup />

            <MeasurementTool />

            <CalculateAreaGroup />

            <NavMesh />

            <DxfFile />

            <LayoutImage />
        </>
    );
}
