import React, { useEffect, useRef, useState } from 'react';
import * as THREE from 'three';
import { useEventsStore } from '../../../../../store/simulation/useEventsStore';
import useModuleStore from '../../../../../store/useModuleStore';
import { TransformControls } from '@react-three/drei';
import { detectModifierKeys } from '../../../../../utils/shortcutkeys/detectModifierKeys';
import { useSelectedEventSphere, useSelectedEventData } from '../../../../../store/simulation/useSimulationStore';

function PointsCreator() {
    const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
    const { activeModule } = useModuleStore();
    const transformRef = useRef<any>(null);
    const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
    const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
    const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere } = useSelectedEventSphere();
    const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData();

    useEffect(() => {
        if (selectedEventSphere) {
            const eventData = getEventByModelUuid(selectedEventSphere.userData.modelUuid);
            if (eventData) {
                setSelectedEventData(
                    eventData,
                    selectedEventSphere.userData.pointUuid
                );
            } else {
                clearSelectedEventData();
            }
        } else {
            clearSelectedEventData();
        }
    }, [selectedEventSphere]);

    useEffect(() => {
        const handleKeyDown = (e: KeyboardEvent) => {
            const keyCombination = detectModifierKeys(e);
            if (!selectedEventSphere) return;
            if (keyCombination === "G") {
                setTransformMode((prev) => (prev === "translate" ? null : "translate"));
            }
            if (keyCombination === "R") {
                setTransformMode((prev) => (prev === "rotate" ? null : "rotate"));
            }
        };

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

    const updatePointToState = (selectedEventSphere: THREE.Mesh) => {
        let point = JSON.parse(JSON.stringify(getPointByUuid(selectedEventSphere.userData.modelUuid, selectedEventSphere.userData.pointUuid)));
        if (point) {
            point.position = [selectedEventSphere.position.x, selectedEventSphere.position.y, selectedEventSphere.position.z];
            updatePoint(selectedEventSphere.userData.modelUuid, selectedEventSphere.userData.pointUuid, point)
        }
    }

    return (
        <>
            {activeModule === 'simulation' &&
                <>
                    <group name='EventPointsGroup' >
                        {events.map((event, i) => {
                            if (event.type === 'transfer') {
                                return (
                                    <group key={i} position={new THREE.Vector3(...event.position)}>
                                        {event.points.map((point, j) => (
                                            <mesh
                                                name='Event-Sphere'
                                                uuid={point.uuid}
                                                ref={(el) => (sphereRefs.current[point.uuid] = el!)}
                                                onClick={(e) => {
                                                    e.stopPropagation();
                                                    setSelectedEventSphere(sphereRefs.current[point.uuid]);
                                                }}
                                                onPointerMissed={() => {
                                                    clearSelectedEventSphere();
                                                    setTransformMode(null);
                                                }}
                                                key={`${i}-${j}`}
                                                position={new THREE.Vector3(...point.position)}
                                                userData={{ modelUuid: event.modelUuid, pointUuid: point.uuid }}
                                            >
                                                <sphereGeometry args={[0.1, 16, 16]} />
                                                <meshStandardMaterial color="orange" />
                                            </mesh>
                                        ))}
                                    </group>
                                );
                            } else if (event.type === 'vehicle') {
                                return (
                                    <group key={i} position={new THREE.Vector3(...event.position)}>
                                        <mesh
                                            name='Event-Sphere'
                                            uuid={event.point.uuid}
                                            ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
                                            }}
                                            onPointerMissed={() => {
                                                clearSelectedEventSphere();
                                                setTransformMode(null);
                                            }}
                                            position={new THREE.Vector3(...event.point.position)}
                                            userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
                                        >
                                            <sphereGeometry args={[0.1, 16, 16]} />
                                            <meshStandardMaterial color="blue" />
                                        </mesh>
                                    </group>
                                );
                            } else if (event.type === 'roboticArm') {
                                return (
                                    <group key={i} position={new THREE.Vector3(...event.position)}>
                                        <mesh
                                            name='Event-Sphere'
                                            uuid={event.point.uuid}
                                            ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
                                            }}
                                            onPointerMissed={() => {
                                                clearSelectedEventSphere();
                                                setTransformMode(null);
                                            }}
                                            position={new THREE.Vector3(...event.point.position)}
                                            userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
                                        >
                                            <sphereGeometry args={[0.1, 16, 16]} />
                                            <meshStandardMaterial color="green" />
                                        </mesh>
                                    </group>
                                );
                            } else if (event.type === 'machine') {
                                return (
                                    <group key={i} position={new THREE.Vector3(...event.position)}>
                                        <mesh
                                            name='Event-Sphere'
                                            uuid={event.point.uuid}
                                            ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
                                            }}
                                            onPointerMissed={() => {
                                                clearSelectedEventSphere();
                                                setTransformMode(null);
                                            }}
                                            position={new THREE.Vector3(...event.point.position)}
                                            userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
                                        >
                                            <sphereGeometry args={[0.1, 16, 16]} />
                                            <meshStandardMaterial color="purple" />
                                        </mesh>
                                    </group>
                                );
                            } else {
                                return null;
                            }
                        })}
                    </group>
                    {(selectedEventSphere && transformMode) &&
                        <TransformControls ref={transformRef} object={selectedEventSphere} mode={transformMode} onMouseUp={(e) => { updatePointToState(selectedEventSphere) }} />
                    }
                </>
            }
        </>
    );
}

export default PointsCreator;
