import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
import type { VesselAnalysisDto, RiskLevel } from '../types';
import { fetchVesselAnalysis } from '../services/vesselAnalysis';

const POLL_INTERVAL_MS = 5 * 60_000; // 5분
const STALE_MS = 30 * 60_000; // 30분

export interface AnalysisStats {
  total: number;
  critical: number;
  high: number;
  medium: number;
  low: number;
  dark: number;
  spoofing: number;
  clusterCount: number;
}

export interface UseVesselAnalysisResult {
  analysisMap: Map<string, VesselAnalysisDto>;
  stats: AnalysisStats;
  clusters: Map<number, string[]>;
  isLoading: boolean;
  lastUpdated: number;
}

const EMPTY_STATS: AnalysisStats = {
  total: 0, critical: 0, high: 0, medium: 0, low: 0,
  dark: 0, spoofing: 0, clusterCount: 0,
};

export function useVesselAnalysis(enabled: boolean): UseVesselAnalysisResult {
  const mapRef = useRef<Map<string, VesselAnalysisDto>>(new Map());
  const [version, setVersion] = useState(0);
  const [isLoading, setIsLoading] = useState(false);
  const [lastUpdated, setLastUpdated] = useState(0);

  const doFetch = useCallback(async () => {
    if (!enabled) return;
    setIsLoading(true);
    try {
      const items = await fetchVesselAnalysis();
      const now = Date.now();
      const map = mapRef.current;

      // stale 제거
      for (const [mmsi, dto] of map) {
        const ts = new Date(dto.timestamp).getTime();
        if (now - ts > STALE_MS) map.delete(mmsi);
      }

      // 새 결과 merge
      for (const item of items) {
        map.set(item.mmsi, item);
      }

      setLastUpdated(now);
      setVersion(v => v + 1);
    } catch {
      // 에러 시 기존 데이터 유지 (graceful degradation)
    } finally {
      setIsLoading(false);
    }
  }, [enabled]);

  useEffect(() => {
    doFetch();
    const t = setInterval(doFetch, POLL_INTERVAL_MS);
    return () => clearInterval(t);
  }, [doFetch]);

  const analysisMap = mapRef.current;

  const stats = useMemo((): AnalysisStats => {
    if (analysisMap.size === 0) return EMPTY_STATS;
    let critical = 0, high = 0, medium = 0, low = 0, dark = 0, spoofing = 0;
    const clusterIds = new Set<number>();

    for (const dto of analysisMap.values()) {
      const level: RiskLevel = dto.algorithms.riskScore.level;
      if (level === 'CRITICAL') critical++;
      else if (level === 'HIGH') high++;
      else if (level === 'MEDIUM') medium++;
      else low++;

      if (dto.algorithms.darkVessel.isDark) dark++;
      if (dto.algorithms.gpsSpoofing.spoofingScore > 0.5) spoofing++;
      if (dto.algorithms.cluster.clusterId >= 0) {
        clusterIds.add(dto.algorithms.cluster.clusterId);
      }
    }

    return {
      total: analysisMap.size, critical, high, medium, low,
      dark, spoofing, clusterCount: clusterIds.size,
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [version]);

  const clusters = useMemo((): Map<number, string[]> => {
    const result = new Map<number, string[]>();
    for (const [mmsi, dto] of analysisMap) {
      const cid = dto.algorithms.cluster.clusterId;
      if (cid < 0) continue;
      const arr = result.get(cid);
      if (arr) arr.push(mmsi);
      else result.set(cid, [mmsi]);
    }
    return result;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [version]);

  return { analysisMap, stats, clusters, isLoading, lastUpdated };
}
