import { useEffect, useRef, type MutableRefObject } from 'react';
import type maplibregl from 'maplibre-gl';
import type { MapProjectionId } from '../types';

export function useFlyTo(
  mapRef: MutableRefObject<maplibregl.Map | null>,
  projectionRef: MutableRefObject<MapProjectionId>,
  opts: {
    selectedMmsi: number | null;
    shipData: { mmsi: number; lon: number; lat: number }[];
    /** true일 때 selectedMmsi fly-to 스킵 (지도 클릭 선택 시) */
    mapInitiatedSelectRef: MutableRefObject<boolean>;
    fleetFocusId: string | number | undefined;
    fleetFocusLon: number | undefined;
    fleetFocusLat: number | undefined;
    fleetFocusZoom: number | undefined;
  },
) {
  const { selectedMmsi, shipData, mapInitiatedSelectRef, fleetFocusId, fleetFocusLon, fleetFocusLat, fleetFocusZoom } = opts;

  // shipData를 ref로 — 의존성에서 제외하여 AIS poll마다 재실행 방지
  const shipDataRef = useRef(shipData);
  useEffect(() => { shipDataRef.current = shipData; }, [shipData]);

  // 패널(좌측 목록)에서 선택 시 해당 선박 위치로 즉시 이동
  useEffect(() => {
    // 지도 내부 클릭에서 발생한 선택이면 스킵
    if (mapInitiatedSelectRef.current) {
      mapInitiatedSelectRef.current = false;
      return;
    }

    const map = mapRef.current;
    if (!map || selectedMmsi == null) return;

    const target = shipDataRef.current.find((t) => t.mmsi === selectedMmsi);
    if (!target || !Number.isFinite(target.lon) || !Number.isFinite(target.lat)) return;

    try {
      const flyOpts = { center: [target.lon, target.lat] as [number, number], duration: 400 };
      if (projectionRef.current === 'globe') {
        map.flyTo(flyOpts);
      } else {
        map.easeTo(flyOpts);
      }
    } catch {
      // ignore — style not ready 등
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedMmsi]);

  // 선단 포커스 이동
  useEffect(() => {
    const map = mapRef.current;
    if (!map || fleetFocusLon == null || fleetFocusLat == null || !Number.isFinite(fleetFocusLon) || !Number.isFinite(fleetFocusLat))
      return;

    try {
      const flyOpts = { center: [fleetFocusLon, fleetFocusLat] as [number, number], zoom: fleetFocusZoom ?? 10, duration: 500 };
      if (projectionRef.current === 'globe') {
        map.flyTo(flyOpts);
      } else {
        map.easeTo(flyOpts);
      }
    } catch {
      // ignore
    }
  }, [fleetFocusId, fleetFocusLon, fleetFocusLat, fleetFocusZoom]);
}
