import * as THREE from 'three'
import { useEffect, useMemo, useState } from 'react'
import { useThree } from '@react-three/fiber';
import { useActiveLayer, useSocketStore, useToggleView, useToolMode } from '../../../../store/builder/store';
import { useAisleStore } from '../../../../store/builder/useAisleStore';
import ReferenceAisle from './referenceAisle';
import { useBuilderStore } from '../../../../store/builder/useBuilderStore';

function AisleCreator() {
    const { scene, camera, raycaster, gl, pointer } = useThree();
    const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
    const { toggleView } = useToggleView();
    const { toolMode } = useToolMode();
    const { activeLayer } = useActiveLayer();
    const { socket } = useSocketStore();
    const { aisles, addAisle } = useAisleStore();

    const [tempPoints, setTempPoints] = useState<Point[]>([]);
    const [isCreating, setIsCreating] = useState(false);
    const { aisleType, aisleWidth, aisleColor } = useBuilderStore();

    // useEffect(() => {
    //     if (tempPoints.length > 0) {
    //         setTempPoints([]);
    //         setIsCreating(false);
    //     }
    // }, [aisleType]);

    const allPoints = useMemo(() => {
        const points: Point[] = [];
        const seenUuids = new Set<string>();

        // Add points from existing aisles
        aisles.forEach(aisle => {
            aisle.points.forEach(point => {
                if (!seenUuids.has(point.uuid)) {
                    seenUuids.add(point.uuid);
                    points.push(point);
                }
            });
        });

        // Add temporary points
        tempPoints.forEach(point => {
            if (!seenUuids.has(point.uuid)) {
                seenUuids.add(point.uuid);
                points.push(point);
            }
        });

        return points;
    }, [aisles, tempPoints]);


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

        let drag = false;
        let isLeftMouseDown = false;

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

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

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

        const onMouseClick = () => {
            if (drag || !toggleView) return;

            raycaster.setFromCamera(pointer, camera);
            const intersectionPoint = new THREE.Vector3();
            const point = raycaster.ray.intersectPlane(plane, intersectionPoint);

            if (!point) return;

            if (['solid-aisle', 'dashed-aisle', 'stripped-aisle', 'dotted-aisle', 'arrows-aisle'].includes(aisleType)) {
                const newPoint: Point = {
                    uuid: THREE.MathUtils.generateUUID(),
                    position: [point.x, point.y, point.z],
                    layer: activeLayer
                };

                if (tempPoints.length === 0) {
                    setTempPoints([newPoint]);
                    setIsCreating(true);
                } else {
                    const aisle: Aisle = {
                        uuid: THREE.MathUtils.generateUUID(),
                        points: [tempPoints[0], newPoint],
                        type: {
                            typeName: 'Aisle',
                            aisleType: aisleType,
                            aisleColor: aisleColor,
                            aisleWidth: aisleWidth
                        }
                    };

                    addAisle(aisle);

                    setTempPoints([newPoint]);
                }
            } else if (['arc-aisle', 'circle-aisle', 'arrow-aisle', 'junction-aisle'].includes(aisleType)) {
                console.log();
            }
        };

        const onContext = (event: any) => {
            event.preventDefault();
            if (isCreating) {
                setTempPoints([]);
                setIsCreating(false);
            }
        };

        if (toolMode === "Aisle" && toggleView) {
            canvasElement.addEventListener("mousedown", onMouseDown);
            canvasElement.addEventListener("mouseup", onMouseUp);
            canvasElement.addEventListener("mousemove", onMouseMove);
            canvasElement.addEventListener("click", onMouseClick);
            canvasElement.addEventListener("contextmenu", onContext);
        } else {
            setTempPoints([]);
            setIsCreating(false);
        }

        return () => {
            canvasElement.removeEventListener("mousedown", onMouseDown);
            canvasElement.removeEventListener("mouseup", onMouseUp);
            canvasElement.removeEventListener("mousemove", onMouseMove);
            canvasElement.removeEventListener("click", onMouseClick);
            canvasElement.removeEventListener("contextmenu", onContext);
        };
    }, [gl, camera, scene, raycaster, pointer, plane, toggleView, toolMode, activeLayer, socket, tempPoints, isCreating, addAisle, aisleType, aisleColor, aisleWidth]);

    return (
        <>
            <group >
                {allPoints.map((point) => (
                    <mesh
                        key={point.uuid}
                        position={new THREE.Vector3(...point.position)}
                    >
                        <sphereGeometry args={[0.1, 16, 16]} />
                        <meshBasicMaterial
                            color={0xffff00}
                        />
                    </mesh>
                ))}
            </group>

            <ReferenceAisle tempPoints={tempPoints} aisleType={aisleType} aisleWidth={aisleWidth} aisleColor={aisleColor} />
        </>
    );
}

export default AisleCreator;