import { Box3, Vector3, Quaternion } from "three";
import { useMemo } from "react";
import { Cylinder } from "@react-three/drei";

export const AssetBoundingBox = ({ name, boundingBox, color, lineWidth, }: { name: string; boundingBox: Box3 | null; color: string; lineWidth: number; }) => {
    const { edgeCylinders, cornerSpheres, center, size } = useMemo(() => {
        if (!boundingBox) {
            return {
                edgeCylinders: [],
                cornerSpheres: [],
                center: new Vector3(),
                size: new Vector3(),
            };
        }

        const min = boundingBox.min;
        const max = boundingBox.max;
        const center = boundingBox.getCenter(new Vector3());
        const size = boundingBox.getSize(new Vector3());

        const corners = [
            new Vector3(min.x, min.y, min.z),
            new Vector3(max.x, min.y, min.z),
            new Vector3(max.x, max.y, min.z),
            new Vector3(min.x, max.y, min.z),
            new Vector3(min.x, min.y, max.z),
            new Vector3(max.x, min.y, max.z),
            new Vector3(max.x, max.y, max.z),
            new Vector3(min.x, max.y, max.z),
        ];

        const edgeIndices: [number, number][] = [
            [0, 1], [1, 2], [2, 3], [3, 0],
            [4, 5], [5, 6], [6, 7], [7, 4],
            [0, 4], [1, 5], [2, 6], [3, 7],
        ];

        const radius = 0.005 * lineWidth;

        const edgeCylinders = edgeIndices.map(([startIdx, endIdx], i) => {
            const start = corners[startIdx];
            const end = corners[endIdx];
            const direction = new Vector3().subVectors(end, start);
            const length = direction.length();
            const midPoint = new Vector3().addVectors(start, end).multiplyScalar(0.5);
            const quaternion = new Quaternion().setFromUnitVectors(
                new Vector3(0, 1, 0),
                direction.clone().normalize()
            );

            return {
                key: `edge-cylinder-${i}`,
                position: midPoint,
                rotation: quaternion,
                length,
                radius,
            };
        });

        const cornerSpheres = corners.map((corner, i) => ({
            key: `corner-sphere-${i}`,
            position: corner.clone(),
            radius: radius * 1.5,
        }));

        return { edgeCylinders, cornerSpheres, center, size };
    }, [boundingBox, lineWidth]);

    if (!boundingBox) return null;

    return (
        <group name={name}>
            {edgeCylinders.map(({ key, position, rotation, length, radius }) => (
                <Cylinder key={key} args={[radius, radius, length, 6]} position={position} quaternion={rotation}>
                    <meshBasicMaterial color={color} depthWrite={false} />
                </Cylinder>
            ))}

            {cornerSpheres.map(({ key, position, radius }) => (
                <mesh key={key} position={position}>
                    <sphereGeometry args={[radius, 12, 12]} />
                    <meshBasicMaterial color={color} depthWrite={false} />
                </mesh>
            ))}

            <mesh visible={false} position={center}>
                <boxGeometry args={[size.x, size.y, size.z]} />
            </mesh>
        </group>
    );
};
