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

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

    const arc = useMemo(() => {
        if (aisle.points.length < 2 || aisle.type.aisleType !== 'arc-aisle') return null;

        const start = new THREE.Vector3(...aisle.points[0].position);
        const end = new THREE.Vector3(...aisle.points[1].position);
        const width = aisle.type.aisleWidth || 0.5;
        const isFlipped = aisle.type.isFlipped || false;

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

        const perpendicular = new THREE.Vector3(-direction.z, 0, direction.x).normalize();
        if (!isFlipped) perpendicular.negate();

        const arcHeight = length * 0.25;
        const midPoint = new THREE.Vector3().lerpVectors(start, end, 0.5);
        const controlPoint = new THREE.Vector3().copy(midPoint).addScaledVector(perpendicular, arcHeight);

        const widthOffset = perpendicular.clone().multiplyScalar(width / 2);

        const p1 = new THREE.Vector3().copy(start).add(widthOffset);
        const p2 = new THREE.Vector3().copy(end).add(widthOffset);
        const p3 = new THREE.Vector3().copy(end).sub(widthOffset);
        const p4 = new THREE.Vector3().copy(start).sub(widthOffset);

        const shape = new THREE.Shape();
        shape.moveTo(p1.x, p1.z);

        shape.quadraticCurveTo(
            controlPoint.x + widthOffset.x,
            controlPoint.z + widthOffset.z,
            p2.x, p2.z
        );

        shape.lineTo(p3.x, p3.z);

        shape.quadraticCurveTo(
            controlPoint.x - widthOffset.x,
            controlPoint.z - widthOffset.z,
            p4.x, p4.z
        );

        shape.lineTo(p1.x, p1.z);

        return {
            shape,
            position: new THREE.Vector3(0, 0, 0),
            rotationY: 0
        };
    }, [aisle]);

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

    if (!arc) return null;

    return (
        <group
            name='Arc-Aisle'
            uuid={aisle.aisleUuid}
            ref={aisleRef}
            position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
            rotation={[Math.PI / 2, 0, 0]}
            userData={aisle}
            onDoubleClick={handleClick}
            onPointerMissed={() => {
                setSelectedAisle(null);
            }}
        >
            <Extrude
                args={[arc.shape, {
                    depth: 0.01,
                    bevelEnabled: false,
                    curveSegments: 32
                }]}
                receiveShadow
                castShadow
            >
                <meshStandardMaterial
                    color={aisle.type.aisleColor || '#ffffff'}
                    side={THREE.DoubleSide}
                />
            </Extrude>
        </group>
    );
}

export default ArcAisle;