import { useState, useMemo, useRef } from 'react';
import { KOREA_SUBMARINE_CABLES } from '../services/submarineCable';
import { getMarineTrafficCategory } from '../utils/marineTraffic';
import type { Ship, VesselAnalysisDto } from '../types';

interface KoreaFilters {
  illegalFishing: boolean;
  illegalTransship: boolean;
  darkVessel: boolean;
  cableWatch: boolean;
  dokdoWatch: boolean;
  ferryWatch: boolean;
}

interface DokdoAlert {
  mmsi: string;
  name: string;
  dist: number;
  time: number;
}

interface UseKoreaFiltersResult {
  filters: KoreaFilters;
  setFilter: (key: keyof KoreaFilters, value: boolean) => void;
  filteredShips: Ship[];
  transshipSuspects: Set<string>;
  cableWatchSuspects: Set<string>;
  dokdoWatchSuspects: Set<string>;
  dokdoAlerts: DokdoAlert[];
  anyFilterOn: boolean;
}

const TRANSSHIP_DURATION_MS = 60 * 60 * 1000; // 1시간
const ONE_HOUR_MS = 60 * 60 * 1000;
const CABLE_DURATION_MS = 3 * 60 * 60 * 1000; // 3시간
const DOKDO = { lat: 37.2417, lng: 131.8647 };
const TERRITORIAL_DEG = 0.2; // ~22km (12해리)
const ALERT_DEG = 0.4; // ~44km

export function useKoreaFilters(
  koreaShips: Ship[],
  visibleShips: Ship[],
  currentTime: number,
  analysisMap?: Map<string, VesselAnalysisDto>,
): UseKoreaFiltersResult {
  const [filters, setFilters] = useState<KoreaFilters>({
    illegalFishing: false,
    illegalTransship: false,
    darkVessel: false,
    cableWatch: false,
    dokdoWatch: false,
    ferryWatch: false,
  });
  const [dokdoAlerts, setDokdoAlerts] = useState<DokdoAlert[]>([]);

  const proximityStartRef = useRef<Map<string, number>>(new Map());
  const aisHistoryRef = useRef<Map<string, { seen: number[]; lastGapStart: number | null }>>(new Map());
  const cableNearStartRef = useRef<Map<string, number>>(new Map());
  const dokdoAlertedRef = useRef<Set<string>>(new Set());

  const setFilter = (key: keyof KoreaFilters, value: boolean) => {
    setFilters(prev => ({ ...prev, [key]: value }));
  };

  const anyFilterOn =
    filters.illegalFishing ||
    filters.illegalTransship ||
    filters.darkVessel ||
    filters.cableWatch ||
    filters.dokdoWatch ||
    filters.ferryWatch;

  // 불법환적 의심 선박 탐지
  const transshipSuspects = useMemo(() => {
    if (!filters.illegalTransship) return new Set<string>();

    const suspects = new Set<string>();
    const isOffshore = (s: Ship) => {
      const nearCoastWest = s.lng > 125.5 && s.lng < 130.0 && s.lat > 33.5 && s.lat < 38.5;
      if (nearCoastWest) {
        const distFromEastCoast = s.lng - 129.5;
        const distFromWestCoast = 126.0 - s.lng;
        const distFromSouthCoast = 34.5 - s.lat;
        if (distFromEastCoast > 0.15 || distFromWestCoast > 0.15 || distFromSouthCoast > 0.15) return true;
        return false;
      }
      return true;
    };

    const isNearForeignCoast = (s: Ship) => {
      if (s.lng < 123.5 && s.lat > 25 && s.lat < 40) return true;
      if (s.lng > 130.5 && s.lat > 30 && s.lat < 46) return true;
      if (s.lng > 129.1 && s.lng < 129.6 && s.lat > 34.0 && s.lat < 34.8) return true;
      if (s.lng > 129.5 && s.lat > 31 && s.lat < 34) return true;
      return false;
    };

    const candidates = koreaShips.filter(s => {
      if (s.speed >= 2) return false;
      const mtCat = getMarineTrafficCategory(s.typecode, s.category);
      if (mtCat !== 'tanker' && mtCat !== 'cargo' && mtCat !== 'fishing') return false;
      if (isNearForeignCoast(s)) return false;
      return isOffshore(s);
    });

    const now = currentTime;
    const prevMap = proximityStartRef.current;
    const currentPairs = new Set<string>();
    const PROXIMITY_DEG = 0.001; // ~110m

    for (let i = 0; i < candidates.length; i++) {
      for (let j = i + 1; j < candidates.length; j++) {
        const a = candidates[i];
        const b = candidates[j];
        const dlat = Math.abs(a.lat - b.lat);
        const dlng = Math.abs(a.lng - b.lng) * Math.cos((a.lat * Math.PI) / 180);
        if (dlat < PROXIMITY_DEG && dlng < PROXIMITY_DEG) {
          const pairKey = [a.mmsi, b.mmsi].sort().join(':');
          currentPairs.add(pairKey);
          if (!prevMap.has(pairKey)) {
            prevMap.set(pairKey, now);
          }
          const pairStartTime = prevMap.get(pairKey)!;
          if (now - pairStartTime >= TRANSSHIP_DURATION_MS) {
            suspects.add(a.mmsi);
            suspects.add(b.mmsi);
          }
        }
      }
    }

    for (const key of prevMap.keys()) {
      if (!currentPairs.has(key)) prevMap.delete(key);
    }

    return suspects;
  }, [koreaShips, filters.illegalTransship, currentTime]);

  // 다크베셀 탐지: AIS 신호 이력 추적
  const darkVesselSet = useMemo(() => {
    if (!filters.darkVessel) return new Set<string>();

    const now = currentTime;
    const history = aisHistoryRef.current;
    const result = new Set<string>();
    const currentMmsis = new Set(koreaShips.map(s => s.mmsi));

    for (const s of koreaShips) {
      let h = history.get(s.mmsi);
      if (!h) {
        h = { seen: [], lastGapStart: null };
        history.set(s.mmsi, h);
      }
      if (h.lastGapStart !== null) {
        const gapDuration = now - h.lastGapStart;
        if (gapDuration >= ONE_HOUR_MS) {
          result.add(s.mmsi);
        }
        h.lastGapStart = null;
      }
      h.seen.push(now);
      if (h.seen.length > 20) h.seen = h.seen.slice(-20);

      const aisAge = now - s.lastSeen;
      if (aisAge > ONE_HOUR_MS) {
        result.add(s.mmsi);
      }

      if (h.seen.length >= 4) {
        let gapCount = 0;
        for (let k = 1; k < h.seen.length; k++) {
          const gap = h.seen[k] - h.seen[k - 1];
          if (gap > 150_000) gapCount++;
        }
        if (gapCount >= 3) {
          result.add(s.mmsi);
        }
      }
    }

    for (const [mmsi, h] of history.entries()) {
      if (!currentMmsis.has(mmsi) && h.lastGapStart === null) {
        h.lastGapStart = now;
      }
    }

    const SIX_HOURS = 6 * ONE_HOUR_MS;
    for (const [mmsi, h] of history.entries()) {
      if (h.seen.length > 0 && now - h.seen[h.seen.length - 1] > SIX_HOURS && !currentMmsis.has(mmsi)) {
        history.delete(mmsi);
      }
    }

    // Python 분류 결과 합집합: is_dark=true인 mmsi 추가
    if (analysisMap) {
      for (const [mmsi, dto] of analysisMap.entries()) {
        if (dto.algorithms.darkVessel.isDark) {
          result.add(mmsi);
        }
      }
    }

    return result;
  }, [koreaShips, filters.darkVessel, currentTime, analysisMap]);

  // 해저케이블 감시
  const cableWatchSet = useMemo(() => {
    if (!filters.cableWatch) return new Set<string>();
    const result = new Set<string>();
    const CABLE_PROX_DEG = 0.01; // ~1.1km

    const segments: [number, number, number, number][] = [];
    for (const cable of KOREA_SUBMARINE_CABLES) {
      for (let k = 0; k < cable.route.length - 1; k++) {
        segments.push([cable.route[k][0], cable.route[k][1], cable.route[k + 1][0], cable.route[k + 1][1]]);
      }
    }

    const distToSegment = (px: number, py: number, x1: number, y1: number, x2: number, y2: number) => {
      const dx = x2 - x1;
      const dy = y2 - y1;
      if (dx === 0 && dy === 0) return Math.hypot(px - x1, py - y1);
      const t = Math.max(0, Math.min(1, ((px - x1) * dx + (py - y1) * dy) / (dx * dx + dy * dy)));
      const cx = x1 + t * dx;
      const cy = y1 + t * dy;
      const dlng = (px - cx) * Math.cos((py * Math.PI) / 180);
      return Math.hypot(dlng, py - cy);
    };

    const now = currentTime;
    const prevMap = cableNearStartRef.current;
    const currentNear = new Set<string>();

    for (const s of koreaShips) {
      if (s.speed > 0.6) continue;
      let nearCable = false;
      for (const [x1, y1, x2, y2] of segments) {
        if (distToSegment(s.lng, s.lat, x1, y1, x2, y2) < CABLE_PROX_DEG) {
          nearCable = true;
          break;
        }
      }
      if (!nearCable) continue;

      currentNear.add(s.mmsi);
      if (!prevMap.has(s.mmsi)) {
        prevMap.set(s.mmsi, now);
      }
      const cableStartTime = prevMap.get(s.mmsi)!;
      if (now - cableStartTime >= CABLE_DURATION_MS) {
        result.add(s.mmsi);
      }
    }

    for (const mmsi of prevMap.keys()) {
      if (!currentNear.has(mmsi)) prevMap.delete(mmsi);
    }

    return result;
  }, [koreaShips, filters.cableWatch, currentTime]);

  // 독도감시
  const dokdoWatchSet = useMemo(() => {
    if (!filters.dokdoWatch) return new Set<string>();
    const result = new Set<string>();
    const newAlerts: DokdoAlert[] = [];
    const alerted = dokdoAlertedRef.current;

    for (const s of koreaShips) {
      if (s.flag !== 'JP') continue;
      const dDokdo = Math.hypot(
        (s.lng - DOKDO.lng) * Math.cos((DOKDO.lat * Math.PI) / 180),
        s.lat - DOKDO.lat,
      );
      if (dDokdo < TERRITORIAL_DEG) {
        result.add(s.mmsi);
        if (!alerted.has(s.mmsi)) {
          alerted.add(s.mmsi);
          const distKm = Math.round(dDokdo * 111);
          newAlerts.push({ mmsi: s.mmsi, name: s.name || s.mmsi, dist: distKm, time: currentTime });
        }
      } else if (dDokdo < ALERT_DEG) {
        result.add(s.mmsi);
        if (!alerted.has(`warn-${s.mmsi}`)) {
          alerted.add(`warn-${s.mmsi}`);
          const distKm = Math.round(dDokdo * 111);
          newAlerts.push({ mmsi: s.mmsi, name: s.name || s.mmsi, dist: distKm, time: currentTime });
        }
      }
    }

    const currentJP = new Set(koreaShips.filter(s => s.flag === 'JP').map(s => s.mmsi));
    for (const key of alerted) {
      const mmsi = key.replace('warn-', '');
      if (!currentJP.has(mmsi)) alerted.delete(key);
    }

    if (newAlerts.length > 0) {
      setDokdoAlerts(prev => [...newAlerts, ...prev].slice(0, 10));
    }

    return result;
  }, [koreaShips, filters.dokdoWatch, currentTime]);

  // 필터링된 선박 목록
  const filteredShips = useMemo(() => {
    if (!anyFilterOn) return visibleShips;
    return visibleShips.filter(s => {
      const mtCat = getMarineTrafficCategory(s.typecode, s.category);
      if (filters.illegalFishing) {
        if (mtCat === 'fishing' && s.flag !== 'KR') return true;
        const riskLevel = analysisMap?.get(s.mmsi)?.algorithms.riskScore.level;
        if (mtCat === 'fishing' && (riskLevel === 'CRITICAL' || riskLevel === 'HIGH')) return true;
      }
      if (filters.illegalTransship && transshipSuspects.has(s.mmsi)) return true;
      if (filters.darkVessel && darkVesselSet.has(s.mmsi)) return true;
      if (filters.cableWatch && cableWatchSet.has(s.mmsi)) return true;
      if (filters.dokdoWatch && dokdoWatchSet.has(s.mmsi)) return true;
      if (filters.ferryWatch && getMarineTrafficCategory(s.typecode, s.category) === 'passenger') return true;
      return false;
    });
  }, [visibleShips, filters, anyFilterOn, transshipSuspects, darkVesselSet, cableWatchSet, dokdoWatchSet, analysisMap]);

  return {
    filters,
    setFilter,
    filteredShips,
    transshipSuspects,
    cableWatchSuspects: cableWatchSet,
    dokdoWatchSuspects: dokdoWatchSet,
    dokdoAlerts,
    anyFilterOn,
  };
}
