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

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

    const userId = localStorage.getItem('userId') ?? '';

    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("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 = () => {
            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("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);

                const comment: CommentSchema = {
                    state: 'active',
                    commentId: MathUtils.generateUUID(),
                    creatorId: userId,
                    createdAt: new Date().toISOString(),
                    comment: '',
                    lastUpdatedAt: new Date().toISOString(),
                    position: position.toArray(),
                    rotation: [0, 0, 0],
                    replies: []
                }

                addComment(comment);
                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