import { useEffect, useRef } from 'react';
import { useThree, useFrame } from '@react-three/fiber';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { setViewport } from './viewportLabelStore';

/**
 * STABLE VIEWPORT CORE — native OrbitControls wrapper.
 * Uses three/addons/controls/OrbitControls.js (NOT Drei). One instance, attached
 * to the active camera and renderer DOM element, updated each frame, disposed
 * exactly once on unmount. Supports rotate, zoom and pan. No shader helpers.
 */
export default function NativeOrbitControls({
  target = [0, 0, 0],
  minDistance = 120,
  maxDistance = 1600,
  enableDamping = true,
  dampingFactor = 0.12,
  enabled = true,
}) {
  const { camera, gl } = useThree();
  const controlsRef = useRef(null);

  useEffect(() => {
    const controls = new OrbitControls(camera, gl.domElement);
    controls.enableDamping = enableDamping;
    controls.dampingFactor = dampingFactor;
    controls.minDistance = minDistance;
    controls.maxDistance = maxDistance;
    controls.target.set(target[0], target[1], target[2]);
    controls.enabled = enabled;
    controlsRef.current = controls;
    setViewport({ controlsCount: 1 });
    return () => {
      controls.dispose();
      controlsRef.current = null;
      setViewport({ controlsCount: 0 });
    };
    // camera/gl are stable for a given Canvas; recreate only if they change.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [camera, gl]);

  const targetKey = target.join(',');
  useEffect(() => {
    if (controlsRef.current) controlsRef.current.target.set(target[0], target[1], target[2]);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [targetKey]);

  useEffect(() => {
    if (controlsRef.current) controlsRef.current.enabled = enabled;
  }, [enabled]);

  useFrame(() => {
    controlsRef.current?.update();
  });

  return null;
}