import { useEffect, useMemo } from "react";
import { Canvas } from "@react-three/fiber";
import { Physics } from "@react-three/rapier";
import { Color, SRGBColorSpace } from "three";
import { KeyboardControls, Stats } from "@react-three/drei";
import { useSceneContext } from "./sceneContext";

import Builder from "../builder/builder";
import Visualization from "../visualization/visualization";
import Setup from "./setup/setup";
import Simulation from "../simulation/simulation";
import PhysicsSimulator from "./physics/physicsSimulator";
import Collaboration from "../collaboration/collaboration";
import useModuleStore from "../../store/useModuleStore";
import { useParams } from "react-router-dom";
import { getAllProjects } from "../../services/dashboard/getAllProjects";
import { getUserData } from "../../functions/getUserData";
import { useLoadingProgress, useSocketStore } from "../../store/builder/store";

export default function Scene({ layout }: { readonly layout: 'Main Layout' | 'Comparison Layout' }) {
    const map = useMemo(() => [
        { name: "forward", keys: ["ArrowUp", "w", "W"] },
        { name: "backward", keys: ["ArrowDown", "s", "S"] },
        { name: "left", keys: ["ArrowLeft", "a", "A"] },
        { name: "right", keys: ["ArrowRight", "d", "D"] },
    ], []);
    const { assetStore } = useSceneContext();
    const { assets } = assetStore();
    const { userId, organization } = getUserData();
    const { projectId } = useParams();
    const { projectSocket } = useSocketStore();
    const { activeModule } = useModuleStore();
    const { loadingProgress } = useLoadingProgress();

    useEffect(() => {
        if (!projectId && loadingProgress > 1) return;
        getAllProjects(userId, organization)
            .then((projects) => {
                if (!projects || !projects.Projects) return;
                let project = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId);
                const canvas = document.getElementById("sceneCanvas")?.getElementsByTagName('canvas')[0];
                if (!canvas) return;
                const screenshotDataUrl = (canvas as HTMLCanvasElement)?.toDataURL("image/png");
                const updateProjects = {
                    projectId: project?.projectUuid,
                    organization,
                    userId,
                    projectName: project?.projectName,
                    thumbnail: screenshotDataUrl,
                };
                if (projectSocket) {
                    projectSocket.emit("v1:project:update", updateProjects);
                }
            }).catch((err) => {
                console.error(err);
            });
            // eslint-disable-next-line
    }, [activeModule, assets, loadingProgress])

    return (
        <KeyboardControls map={map}>
            <Canvas
                id="sceneCanvas"
                shadows
                color="#aaaa"
                eventPrefix="client"
                onContextMenu={(e) => {
                    e.preventDefault();
                }}
                performance={{ min: 0.9, max: 1.0 }}
                onCreated={(e) => {
                    e.scene.background = layout === 'Main Layout' ? null : new Color(0x19191d);
                }}
                gl={{ outputColorSpace: SRGBColorSpace, powerPreference: "high-performance", antialias: true, preserveDrawingBuffer: true }}
            >
                <Setup />
                <Collaboration />
                <Physics gravity={[0, -9.81, 0]} allowedLinearError={50} numSolverIterations={50} debug >
                    <Builder />

                    <Simulation />

                    <PhysicsSimulator />
                </Physics>
                <Visualization />
                <Stats />
            </Canvas>
        </KeyboardControls>
    );
}
