import { useEffect, useRef } from "react";
import { useFrame, useThree } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
import * as THREE from "three";
import type { Vec3 } from "./types";

type CameraRigProps = {
  target?: Vec3 | null;
  orbit?: boolean;
  distance?: number;
};

export function CameraRig({ target, orbit = false, distance = 90 }: CameraRigProps) {
  const controlsRef = useRef<any>(null);
  const { camera } = useThree();
  const desired = useRef(new THREE.Vector3(0, 0, 0));
  const lastTarget = useRef<THREE.Vector3 | null>(null);

  useEffect(() => {
    if (target) {
      desired.current.set(target[0], target[1], target[2]);
      lastTarget.current ??= desired.current.clone();
    }
  }, [target]);

  useFrame((_, dt) => {
    if (!target) return;
    const previous = lastTarget.current ?? desired.current;
    const movement = desired.current.clone().sub(previous);
    if (movement.lengthSq() > 0) camera.position.add(movement);
    lastTarget.current = desired.current.clone();

    const current = controlsRef.current?.target;
    if (current) {
      current.lerp(desired.current, Math.min(1, dt * 3));
      controlsRef.current.update();
    } else {
      camera.lookAt(desired.current);
    }
  });

  if (!orbit) return null;
  return <OrbitControls ref={controlsRef} enableDamping dampingFactor={0.08} minDistance={10} maxDistance={distance * 5} makeDefault />;
}
