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

import * as THREE from "three";
import { useEffect, useRef } from "react";
import { useThree } from "@react-three/fiber";
import { Bvh } from "@react-three/drei";

//////////  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";

export default function Builder() {
    const state = useThree<Types.ThreeState>(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements.

    // Assigning the scene and camera from the Three.js state to the references.

    const plane = useRef<THREE.Mesh>(null); // Reference for a plane object for raycaster reference.
    const grid = useRef() as any; // Reference for a grid object for raycaster reference.

    const { toggleView } = useToggleView(); // State for toggling between 2D and 3D.
    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();

    // 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);

    //////////  All Toggle's //////////

    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();
    }, []);

    //////////  Return  //////////

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

            <SocketResponses />

            {/* <WallsAndWallItems
                CSGGroup={CSGGroup}
                setSelectedItemsIndex={setSelectedItemsIndex}
                selectedItemsIndex={selectedItemsIndex}
                currentWallItem={currentWallItem}
                csg={csg}
                lines={lines}
                hoveredDeletableWallItem={hoveredDeletableWallItem}
            /> */}

            <AssetsGroup plane={plane} />

            <AislesGroup />

            <WallGroup />

            <FloorGroup />

            <ZoneGroup />

            <MeasurementTool />

            <CalculateAreaGroup />

            <NavMesh />

            <DxfFile />

            <LayoutImage />
        </>
    );
}
