import { useEffect, useMemo, useRef, useState } from 'react';
import type { AisTarget } from '../../entities/aisTarget/model/types';
import type { ShipImageInfo } from '../../entities/shipImage/model/types';
import { fetchShipImagesByImo } from '../../entities/shipImage/api/fetchShipImages';

const BATCH_SIZE = 5;

/**
 * 대상선박(chnprmship)의 IMO별 이미지 메타데이터를 일괄 조회.
 * IMO 단위 캐시로 중복 요청 방지, storeRef + rev 패턴으로 프로그레시브 갱신.
 */
export function useShipImageMap(opts: {
  targets: AisTarget[];
  enabled?: boolean;
}): Map<number, ShipImageInfo[]> {
  const { targets, enabled = true } = opts;

  // IMO → images 캐시 (컴포넌트 수명 동안 유지)
  const cacheRef = useRef<Map<number, ShipImageInfo[]>>(new Map());
  // mmsi → images 결과 (렌더링용)
  const storeRef = useRef<Map<number, ShipImageInfo[]>>(new Map());
  const [rev, setRev] = useState(0);

  // 고유 { mmsi, imo } 쌍 추출 (imo > 0만)
  const entries = useMemo(() => {
    const seen = new Set<number>();
    const result: Array<{ mmsi: number; imo: number }> = [];
    for (const t of targets) {
      if (t.imo > 0 && !seen.has(t.mmsi)) {
        seen.add(t.mmsi);
        result.push({ mmsi: t.mmsi, imo: t.imo });
      }
    }
    return result;
  }, [targets]);

  useEffect(() => {
    if (!enabled || entries.length === 0) return;

    const ac = new AbortController();
    let cancelled = false;

    (async () => {
      // 캐시에 없는 IMO만 추출
      const uncachedImos = new Set<number>();
      for (const e of entries) {
        if (!cacheRef.current.has(e.imo)) uncachedImos.add(e.imo);
      }

      // batch fetch (BATCH_SIZE 병렬)
      const imoArr = Array.from(uncachedImos);
      for (let i = 0; i < imoArr.length; i += BATCH_SIZE) {
        if (cancelled) return;
        const batch = imoArr.slice(i, i + BATCH_SIZE);
        const results = await Promise.allSettled(
          batch.map((imo) => fetchShipImagesByImo(imo, ac.signal)),
        );
        for (let j = 0; j < batch.length; j++) {
          const r = results[j];
          const images = r.status === 'fulfilled' ? r.value : [];
          cacheRef.current.set(batch[j], images);
        }
      }

      if (cancelled) return;

      // mmsi → images 매핑 재구성
      const next = new Map<number, ShipImageInfo[]>();
      for (const e of entries) {
        const imgs = cacheRef.current.get(e.imo);
        if (imgs && imgs.length > 0) next.set(e.mmsi, imgs);
      }
      storeRef.current = next;
      setRev((v) => v + 1);
    })();

    return () => {
      cancelled = true;
      ac.abort();
    };
  }, [entries, enabled]);

  // rev를 의존성으로 두어 storeRef 갱신 시 새 참조 반환
  // eslint-disable-next-line react-hooks/exhaustive-deps
  return useMemo(() => storeRef.current, [rev]);
}
