import { useEffect } from "react";
import { useThree } from "@react-three/fiber";
import * as THREE from "three";
import type { CameraControls } from "@react-three/drei";

const CameraShortcutsControls = () => {
    const { camera, controls } = useThree();
    
    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;

            // get current target
            const target = new THREE.Vector3();
            cc.getTarget(target);

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

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

            if (isTextInput(document.activeElement)) return;

            switch (e.key) {
                case "1": // Front
                    pos = new THREE.Vector3(0, 0, distance).add(target);
                    break;
                case "3": // Right
                    pos = new THREE.Vector3(distance, 0, 0).add(target);
                    break;
                case "7": // Top
                    pos = new THREE.Vector3(0, distance, 0).add(target);
                    break;
                case "9": {
                    // Opposite view logic
                    if (Math.abs(dir.z) > Math.abs(dir.x) && Math.abs(dir.z) > Math.abs(dir.y)) {
                        // Currently looking Front/Back → flip Z
                        pos = new THREE.Vector3(0, 0, -Math.sign(dir.z) * distance).add(target);
                    } else if (Math.abs(dir.x) > Math.abs(dir.z) && Math.abs(dir.x) > Math.abs(dir.y)) {
                        // Currently looking Right/Left → flip X
                        pos = new THREE.Vector3(-Math.sign(dir.x) * distance, 0, 0).add(target);
                    } else {
                        // Currently looking Top/Bottom → stay Top
                        pos = new THREE.Vector3(0, distance, 0).add(target);
                    }
                    break;
                }
            }

            if (pos) {
                cc.setLookAt(
                    pos.x, pos.y, pos.z, // camera position
                    target.x, target.y, target.z, // keep same target
                    true // smooth transition
                );
            }
        };

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

    return null;
};

export default CameraShortcutsControls;
