import { useState, useMemo, useRef } from 'react';
import { useLocalStorage } from './useLocalStorage';
import { KOREA_SUBMARINE_CABLES } from '../services/submarineCable';
// mtCategory는 Ship 객체에 사전 계산됨 (useKoreaData)
import { classifyFishingZone } from '../utils/fishingAnalysis';
import type { Ship, VesselAnalysisDto } from '../types';

interface KoreaFilters {
  illegalFishing: boolean;
  illegalTransship: boolean;
  darkVessel: boolean;
  cableWatch: boolean;
  dokdoWatch: boolean;
  ferryWatch: boolean;
  cnFishing: 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>;
  cnFishingSuspects: Set<string>;
  dokdoAlerts: DokdoAlert[];
  anyFilterOn: boolean;
}

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

// currentTime 파라미터 제거 — 데이터(koreaShips) 변경 시에만 재계산.
// 타임스탬프가 필요한 곳은 Date.now() 인라인 사용.
export function useKoreaFilters(
  koreaShips: Ship[],
  visibleShips: Ship[],
  analysisMap?: Map<string, VesselAnalysisDto>,
): UseKoreaFiltersResult {
  const [filters, setFilters] = useLocalStorage<KoreaFilters>('koreaFilters', {
    illegalFishing: false,
    illegalTransship: false,
    darkVessel: false,
    cableWatch: false,
    dokdoWatch: false,
    ferryWatch: false,
    cnFishing: false,
  });
  const [dokdoAlerts, setDokdoAlerts] = useState<DokdoAlert[]>([]);

  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 ||
    filters.cnFishing;

  // 불법환적 의심 선박 탐지 (Python 분석 결과 소비)
  const transshipSuspects = useMemo(() => {
    if (!filters.illegalTransship) return new Set<string>();
    const result = new Set<string>();
    if (analysisMap) {
      for (const [mmsi, dto] of analysisMap) {
        if (dto.algorithms.transship?.isSuspect) result.add(mmsi);
      }
    }
    return result;
  }, [filters.illegalTransship, analysisMap]);

  // 다크베셀 탐지: AIS 신호 이력 추적
  // currentTime 제거 → koreaShips(5분 polling) 변경 시에만 재계산
  const darkVesselSet = useMemo(() => {
    if (!filters.darkVessel) return new Set<string>();

    const now = Date.now();
    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, analysisMap]);

  // 해저케이블 감시
  // currentTime 제거 → koreaShips(5분 polling) 변경 시에만 재계산
  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 = Date.now();
    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 제거 → koreaShips(5분 polling) 변경 시에만 재계산
  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: Date.now() });
        }
      } 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: Date.now() });
        }
      }
    }

    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]);

  // 중국어선 의심 선박 Set (어구 + 모선 포함)
  const cnFishingSuspects = useMemo(() => {
    if (!filters.cnFishing) return new Set<string>();
    const result = new Set<string>();
    const gearRe = /^(.+?)_\d+_\d+_?$/;

    // 모선명 → mmsi 맵 (어구가 아닌 선박)
    const nameToMmsi = new Map<string, string>();
    for (const s of koreaShips) {
      const nm = (s.name || '').trim();
      if (nm && !gearRe.test(nm)) nameToMmsi.set(nm, s.mmsi);
    }

    // 어구 + CN 어선 추가, 모선명 수집
    const parentNames = new Set<string>();
    for (const s of koreaShips) {
      const isCnFishing = s.flag === 'CN' && s.mtCategory === 'fishing';
      const m = (s.name || '').match(gearRe);
      if (isCnFishing || m) {
        result.add(s.mmsi);
        if (m) parentNames.add(m[1].trim());
      }
    }

    // 모선도 포함
    for (const pName of parentNames) {
      const mmsi = nameToMmsi.get(pName);
      if (mmsi) result.add(mmsi);
    }

    return result;
  }, [filters.cnFishing, koreaShips]);

  // 필터링된 선박 목록
  const filteredShips = useMemo(() => {
    if (!anyFilterOn) return visibleShips;
    return visibleShips.filter(s => {
      if (filters.illegalFishing) {
        // 특정어업수역 Ⅰ~Ⅳ 내 비한국 어선만 불법어선으로 판별
        if (s.mtCategory === 'fishing' && s.flag !== 'KR') {
          const zoneInfo = classifyFishingZone(s.lat, s.lng);
          if (zoneInfo.zone !== 'OUTSIDE') return true;
        }
        // Python 분석: 영해/접속수역 침범
        const analysis = analysisMap?.get(s.mmsi);
        if (analysis) {
          const zone = analysis.algorithms.location.zone;
          if (zone === 'TERRITORIAL_SEA' || zone === 'CONTIGUOUS_ZONE') 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 && s.mtCategory === 'passenger') return true;
      if (filters.cnFishing && cnFishingSuspects.has(s.mmsi)) return true;
      return false;
    });
  }, [visibleShips, filters, anyFilterOn, transshipSuspects, darkVesselSet, cableWatchSet, dokdoWatchSet, analysisMap, cnFishingSuspects]);

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