import { useEffect, useState } from "react";
import { useThree } from "@react-three/fiber";
import { Vector3 } from "three";
import CommentInstances from "./instances/commentInstances";
import { Sphere } from "@react-three/drei";
import { useActiveTool, useSelectedComment } from "../../../store/builder/store";

function CommentsGroup() {
    const { gl, raycaster, camera, scene, pointer, size } = useThree();
    const { activeTool } = useActiveTool();
    const [hoverPos, setHoverPos] = useState<Vector3 | null>(null);
    const { setSelectedComment, setCommentPositionState, setPosition2Dstate } = useSelectedComment();

    useEffect(() => {
        const canvasElement = gl.domElement;

        let drag = false;
        let isLeftMouseDown = false;

        const onMouseDown = (evt: MouseEvent) => {
            if (evt.button === 0) {
                isLeftMouseDown = true;
                drag = false;
            }
        };

        const onMouseUp = (evt: MouseEvent) => {
            if (evt.button === 0) {
                isLeftMouseDown = false;
            }
        }

        const onMouseMove = () => {
            if (isLeftMouseDown) {
                drag = true;
            }

            raycaster.setFromCamera(pointer, camera);
            const intersects = raycaster
                .intersectObjects(scene.children, true)
                .filter(
                    (intersect) =>
                        !intersect.object.name.includes("Roof") &&
                        !intersect.object.name.includes("MeasurementReference") &&
                        !intersect.object.name.includes("agv-collider") &&
                        !intersect.object.name.includes("zonePlane") &&
                        !intersect.object.name.includes("SelectionGroup") &&
                        !intersect.object.name.includes("selectionAssetGroup") &&
                        !intersect.object.name.includes("commentHolder") &&
                        !intersect.object.name.includes("SelectionGroupBoundingBoxLine") &&
                        !intersect.object.name.includes("SelectionGroupBoundingBox") &&
                        !intersect.object.name.includes("SelectionGroupBoundingLine") &&
                        intersect.object.type !== "GridHelper"
                );

            if (intersects.length > 0) {
                const point = intersects[0].point;
                setHoverPos(new Vector3(point.x, Math.max(point.y, 0), point.z));
            } else {
                setHoverPos(null);
            }
        };

        const onMouseClick = async () => {
            if (drag) return;

            const intersects = raycaster
                .intersectObjects(scene.children, true)
                .filter(
                    (intersect) =>
                        !intersect.object.name.includes("Roof") &&
                        !intersect.object.name.includes("MeasurementReference") &&
                        !intersect.object.name.includes("agv-collider") &&
                        !intersect.object.name.includes("zonePlane") &&
                        !intersect.object.name.includes("SelectionGroup") &&
                        !intersect.object.name.includes("selectionAssetGroup") &&
                        !intersect.object.name.includes("commentHolder") &&
                        !intersect.object.name.includes("SelectionGroupBoundingBoxLine") &&
                        !intersect.object.name.includes("SelectionGroupBoundingBox") &&
                        !intersect.object.name.includes("SelectionGroupBoundingLine") &&
                        intersect.object.type !== "GridHelper"
                );
            if (intersects.length > 0) {
                const position = new Vector3(intersects[0].point.x, Math.max(intersects[0].point.y, 0), intersects[0].point.z);
                setSelectedComment(null);
                setCommentPositionState({ position: position.toArray() })


                position.project(camera);
                const x = (position.x * 0.5 + 0.5) * size.width;
                const y = (-(position.y * 0.5) + 0.5) * size.height;
                setPosition2Dstate({ x, y })
                setHoverPos(null);
            }
        }

        if (activeTool === 'comment') {
            canvasElement.addEventListener("mousedown", onMouseDown);
            canvasElement.addEventListener("mouseup", onMouseUp);
            canvasElement.addEventListener("mousemove", onMouseMove);
            canvasElement.addEventListener("click", onMouseClick);
        } else {
            setHoverPos(null);
        }

        return () => {
            canvasElement.removeEventListener("mousedown", onMouseDown);
            canvasElement.removeEventListener("mouseup", onMouseUp);
            canvasElement.removeEventListener("mousemove", onMouseMove);
            canvasElement.removeEventListener("click", onMouseClick);
        };
    }, [activeTool, camera])

    return (
        <>
            <CommentInstances />
            {hoverPos && (
                <Sphere name={'commentHolder'} args={[0.1, 16, 16]} position={hoverPos}>
                    <meshStandardMaterial color="orange" />
                </Sphere>
            )}
        </>
    )
}

export default CommentsGroup