import { Vector3 } from "three";
import { useEffect } from "react";
import { useThree } from "@react-three/fiber";
import { CameraControls } from "@react-three/drei";
import { useToggleView } from "../../../../store/builder/store";
import useModuleStore from "../../../../store/ui/useModuleStore";
import { useSceneStore } from "../../../../store/scene/useSceneStore";
import * as CONSTANTS from "../../../../types/world/worldConstants";

const CameraShortcutsControls = () => {
    const { camera, controls } = useThree();
    const { toggleView } = useToggleView();
    const { camType, setCamType } = useSceneStore();
    const { activeModule } = useModuleStore();

    const isTextInput = (element: Element | null): boolean => element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element?.getAttribute("contenteditable") === "true";

    useEffect(() => {
        const handleKeyDown = (e: KeyboardEvent) => {
            if (!controls) return;

            const cc = controls as CameraControls;

            const target = new Vector3();
            cc.getTarget(target);

            const distance = camera.position.distanceTo(target);
            let pos: Vector3 | null = null;

            const dir = new Vector3().subVectors(camera.position, target).normalize();

            if (isTextInput(document.activeElement)) return;

            switch (e.code) {
                case "Numpad1": // Front
                    pos = new Vector3(0, 0, distance).add(target);
                    LookAt(pos);
                    break;
                case "Numpad3": // Right
                    pos = new Vector3(distance, 0, 0).add(target);
                    LookAt(pos);
                    break;
                case "Numpad7": // Top
                    pos = new Vector3(0, distance, 0).add(target);
                    LookAt(pos);
                    break;
                case "Numpad9": {
                    // Opposite
                    if (Math.abs(dir.z) > Math.abs(dir.x) && Math.abs(dir.z) > Math.abs(dir.y)) {
                        pos = new Vector3(0, 0, -Math.sign(dir.z) * distance).add(target);
                        LookAt(pos);
                    } else if (Math.abs(dir.x) > Math.abs(dir.z) && Math.abs(dir.x) > Math.abs(dir.y)) {
                        pos = new Vector3(-Math.sign(dir.x) * distance, 0, 0).add(target);
                        LookAt(pos);
                    } else {
                        pos = new Vector3(0, distance, 0).add(target);
                        LookAt(pos);
                    }
                    break;
                }
                case "Numpad5": {
                    if (!toggleView) {
                        if (camType === "perspective") {
                            setCamType("orthographic");
                            (controls as any).mouseButtons.left = CONSTANTS.twoDimension.leftMouse;
                            (controls as any).mouseButtons.right = CONSTANTS.twoDimension.rightMouse;
                        } else {
                            setCamType("perspective");
                            (controls as any).mouseButtons.left = CONSTANTS.threeDimension.leftMouse;
                            (controls as any).mouseButtons.right = CONSTANTS.threeDimension.rightMouse;
                        }
                    }
                    break;
                }
            }

            function LookAt(pos: Vector3) {
                cc.setLookAt(pos.x, pos.y, pos.z, target.x, target.y, target.z, true);
            }
        };

        window.addEventListener("keydown", handleKeyDown);
        return () => window.removeEventListener("keydown", handleKeyDown);
    }, [controls, camera, camType, setCamType, toggleView, activeModule]);

    return null;
};

export default CameraShortcutsControls;
