import * as THREE from 'three';
import { useMemo, useRef } from 'react';
import { Instances, Instance } from '@react-three/drei';
import * as Constants from '../../../../../../types/world/worldConstants';
import { useToolMode } from '../../../../../../store/builder/store';
import { useBuilderStore } from '../../../../../../store/builder/useBuilderStore';

function ArrowsAisle({ aisle }: { readonly aisle: Aisle }) {
    const aisleRef = useRef<THREE.Group>(null);
    const { toolMode } = useToolMode();
    const { setSelectedAisle, hoveredPoint } = useBuilderStore();

    const { arrowGeometry, arrowInstances } = useMemo(() => {
        const result = {
            arrowGeometry: null as THREE.ExtrudeGeometry | null,
            arrowInstances: [] as {
                position: [number, number, number];
                rotation: [number, number, number];
            }[],
        };

        if (aisle.points.length < 2 || aisle.type.aisleType !== 'arrows-aisle') return result;

        const start = new THREE.Vector3(...aisle.points[0].position);
        const end = new THREE.Vector3(...aisle.points[1].position);
        const width = aisle.type.aisleWidth || 0.1;
        const arrowLength = aisle.type.aisleLength || 0.6;
        const spacing = aisle.type.gapLength || 0.6;

        const direction = new THREE.Vector3().subVectors(end, start);
        const length = direction.length();
        direction.normalize();

        const count = Math.floor((length + spacing) / (arrowLength + spacing));
        const angle = Math.atan2(direction.x, direction.z) + Math.PI;

        const shape = new THREE.Shape();
        const w = width * 0.8;
        const h = arrowLength;

        shape.moveTo(0, 0);
        shape.lineTo(w, h * 0.6);
        shape.lineTo(w * 0.4, h * 0.6);
        shape.lineTo(w * 0.4, h);
        shape.lineTo(-w * 0.4, h);
        shape.lineTo(-w * 0.4, h * 0.6);
        shape.lineTo(-w, h * 0.6);
        shape.lineTo(0, 0);

        result.arrowGeometry = new THREE.ExtrudeGeometry(shape, {
            depth: 0.01,
            bevelEnabled: false,
        });

        result.arrowGeometry.rotateX(Math.PI / 2);

        for (let i = 0; i < count; i++) {
            const offset = arrowLength + i * (arrowLength + spacing);
            const center = new THREE.Vector3().copy(start).addScaledVector(direction, offset);

            result.arrowInstances.push({
                position: [center.x, 0, center.z],
                rotation: [0, angle, 0],
            });
        }

        return result;
    }, [aisle]);

    const handleClick = () => {
        if (toolMode === 'move' && !hoveredPoint) {
            setSelectedAisle(aisleRef.current);
        }
    };

    if (!arrowGeometry || arrowInstances.length === 0) return null;

    return (
        <group
            name="Arrows-Aisle"
            uuid={aisle.aisleUuid}
            ref={aisleRef}
            position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
            userData={aisle}
            onDoubleClick={handleClick}
            onPointerMissed={() => {
                setSelectedAisle(null);
            }}
        >
            <Instances geometry={arrowGeometry} frustumCulled={false}>
                <meshStandardMaterial color={aisle.type.aisleColor || '#ffffff'} side={THREE.DoubleSide} />
                {arrowInstances.map(({ position, rotation }, i) => (
                    <Instance key={i} position={position} rotation={rotation} />
                ))}
            </Instances>
        </group>
    );
}

export default ArrowsAisle;
