// ═══ 중국 어선 조업 분석 — GC-KCG-2026-001 보고서 기반 ═══
// 한중어업협정 허가현황 (2026.01.06, 906척) + GB/T 5147-2003 어구 분류

import type { Ship } from '../types';
import booleanPointInPolygon from '@turf/boolean-point-in-polygon';
import { point, multiPolygon } from '@turf/helpers';
import type { Feature, MultiPolygon } from 'geojson';

import zone1Data from '../data/zones/특정어업수역Ⅰ.json';
import zone2Data from '../data/zones/특정어업수역Ⅱ.json';
import zone3Data from '../data/zones/특정어업수역Ⅲ.json';
import zone4Data from '../data/zones/특정어업수역Ⅳ.json';

/**
 * 중국 허가 업종 코드 (허가번호 접두사)
 * PT(C21): 2척식저인망 본선 323척 + 부속선(PT-S) 323척
 * OT(C22): 1척식저인망 13척
 * PS(C23): 위망(선망) 16척 (宁波海裕 단일법인)
 * GN(C25): 유망(유자망) 200척
 * FC:      운반선 31척
 */
export type FishingGearType = 'trawl_pair' | 'trawl_single' | 'gillnet' | 'stow_net' | 'purse_seine' | 'carrier' | 'unknown';

export interface FishingAnalysis {
  gearType: FishingGearType;
  gearTypeKo: string;
  permitCode: string;         // PT, OT, GN, PS, FC
  gbCode: string;             // GB/T 5147-2003 코드
  isOperating: boolean;
  operatingStatusKo: string;
  confidence: number;
  riskLevel: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
  riskReason: string;
}

/** 업종별 메타데이터 */
const GEAR_META: Record<FishingGearType, {
  ko: string; icon: string; color: string;
  permitCode: string; gbCode: string;
  speedRange: [number, number]; aiConfidence: string;
}> = {
  trawl_pair:   { ko: '2척식 저인망(PT)', icon: '🔻', color: '#ef4444', permitCode: 'PT', gbCode: 'TDS', speedRange: [2, 5], aiConfidence: '89~95%' },
  trawl_single: { ko: '1척식 저인망(OT)', icon: '🔻', color: '#dc2626', permitCode: 'OT', gbCode: 'TDD', speedRange: [2, 5], aiConfidence: '89~92%' },
  gillnet:      { ko: '유자망(GN)', icon: '🔲', color: '#f97316', permitCode: 'GN', gbCode: 'CLD', speedRange: [0, 2], aiConfidence: '74~80%' },
  stow_net:     { ko: '안강망(Z)', icon: '🪤', color: '#eab308', permitCode: '-', gbCode: 'ZD', speedRange: [0, 1], aiConfidence: '70~78%' },
  purse_seine:  { ko: '위망/선망(PS)', icon: '🔄', color: '#3b82f6', permitCode: 'PS', gbCode: 'WDD', speedRange: [3, 10], aiConfidence: '94~97%' },
  carrier:      { ko: '운반선(FC)', icon: '🚢', color: '#6b7280', permitCode: 'FC', gbCode: '-', speedRange: [0, 12], aiConfidence: '-' },
  unknown:      { ko: '미분류', icon: '🐟', color: '#9ca3af', permitCode: '-', gbCode: '-', speedRange: [0, 0], aiConfidence: '-' },
};

export { GEAR_META as GEAR_LABELS };

/**
 * EPSG:3857 → WGS84 좌표 변환
 */
function epsg3857ToWgs84(x: number, y: number): [number, number] {
  const lon = (x / (Math.PI * 6378137)) * 180;
  const lat = Math.atan(Math.exp(y / 6378137)) * (360 / Math.PI) - 90;
  return [lon, lat]; // GeoJSON [lng, lat] 순서
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function convertZoneToWgs84(data: any): Feature<MultiPolygon> {
  const feat = data.features[0];
  const multiCoords: number[][][][] = feat.geometry.coordinates.map(
    (poly: number[][][]) => poly.map(
      (ring: number[][]) => ring.map(([x, y]: number[]) => epsg3857ToWgs84(x, y)),
    ),
  );
  return multiPolygon(multiCoords).geometry
    ? { type: 'Feature', properties: {}, geometry: { type: 'MultiPolygon', coordinates: multiCoords } }
    : multiPolygon(multiCoords) as unknown as Feature<MultiPolygon>;
}

export type FishingZoneId = 'ZONE_I' | 'ZONE_II' | 'ZONE_III' | 'ZONE_IV' | 'OUTSIDE';

export interface FishingZoneInfo {
  zone: FishingZoneId;
  name: string;
  allowed: string[];
}

/**
 * 특정어업수역 Ⅰ~Ⅳ 폴리곤 (WGS84 변환 캐시)
 */
const ZONE_POLYGONS: { id: FishingZoneId; name: string; allowed: string[]; geojson: Feature<MultiPolygon> }[] = [
  { id: 'ZONE_I', name: '수역Ⅰ(동해)', allowed: ['PS', 'FC'], geojson: convertZoneToWgs84(zone1Data) },
  { id: 'ZONE_II', name: '수역Ⅱ(남해)', allowed: ['PT', 'OT', 'GN', 'PS', 'FC'], geojson: convertZoneToWgs84(zone2Data) },
  { id: 'ZONE_III', name: '수역Ⅲ(서남해)', allowed: ['PT', 'OT', 'GN', 'PS', 'FC'], geojson: convertZoneToWgs84(zone3Data) },
  { id: 'ZONE_IV', name: '수역Ⅳ(서해)', allowed: ['GN', 'PS', 'FC'], geojson: convertZoneToWgs84(zone4Data) },
];

/**
 * 특정어업수역 폴리곤 기반 수역 분류
 */
export function classifyFishingZone(lat: number, lng: number): FishingZoneInfo {
  const pt = point([lng, lat]);
  for (const z of ZONE_POLYGONS) {
    if (booleanPointInPolygon(pt, z.geojson)) {
      return { zone: z.id, name: z.name, allowed: z.allowed };
    }
  }
  return { zone: 'OUTSIDE', name: '수역 외', allowed: [] };
}

/**
 * 업종별 허가 기간 (월/일)
 */
const PERMIT_PERIODS: Record<string, { periods: [number, number, number, number][]; label: string }> = {
  PT: { periods: [[1,1, 4,15], [10,16, 12,31]], label: '1/1~4/15, 10/16~12/31' },
  OT: { periods: [[1,1, 4,15], [10,16, 12,31]], label: '1/1~4/15, 10/16~12/31' },
  GN: { periods: [[2,1, 6,1], [9,1, 12,31]], label: '2/1~6/1, 9/1~12/31' },
  PS: { periods: [[1,1, 12,31]], label: '연중' },
  FC: { periods: [[1,1, 12,31]], label: '연중' },
};

function isInPermitPeriod(permitCode: string, date: Date): boolean {
  const pp = PERMIT_PERIODS[permitCode];
  if (!pp) return false;
  const m = date.getMonth() + 1;
  const d = date.getDate();
  const dayOfYear = m * 100 + d;
  return pp.periods.some(([m1, d1, m2, d2]) => dayOfYear >= m1 * 100 + d1 && dayOfYear <= m2 * 100 + d2);
}

/**
 * AIS 신호 기반 중국 어선 조업 분석 (보고서 4장 기반)
 *
 * 트롤(PT/OT): 2~5kn, Lawn-mowing 지그재그, 방향변화 <30°
 * 자망(GN): 0~2kn 정지·재방문, AIS OFF 빈번
 * 선망(PS): 8~10kn→3kn 급전환, 원형 궤적
 * 운반선(FC): 환적 패턴 (0.5NM 접근 + 2kn이하 + 30분)
 */
export function analyzeFishing(ship: Ship): FishingAnalysis {
  const speed = ship.speed;
  const status = ship.status?.toLowerCase() || '';
  const isAnchored = status.includes('anchor') || status.includes('moor');

  // 방향 변화율 (trail 기반)
  let headingVariance = 0;
  if (ship.trail && ship.trail.length >= 3) {
    const pts = ship.trail.slice(-6);
    const headings: number[] = [];
    for (let i = 1; i < pts.length; i++) {
      const dlng = pts[i][1] - pts[i - 1][1];
      const dlat = pts[i][0] - pts[i - 1][0];
      headings.push(Math.atan2(dlng, dlat) * 180 / Math.PI);
    }
    if (headings.length >= 2) {
      const diffs = headings.slice(1).map((h, i) => {
        let d = Math.abs(h - headings[i]);
        if (d > 180) d = 360 - d;
        return d;
      });
      headingVariance = diffs.reduce((a, b) => a + b, 0) / diffs.length;
    }
  }

  let gearType: FishingGearType = 'unknown';
  let isOperating = false;
  let operatingStatusKo = '이동 중';
  let confidence = 0.3;

  // === 패턴 매칭 (보고서 4.1~4.3 기준) ===

  if (isAnchored || speed > 12) {
    // 정박 또는 고속 이동 → 비조업
    gearType = 'unknown';
    isOperating = false;
    operatingStatusKo = isAnchored ? '정박 중' : '고속 이동';
    confidence = 0.8;

  } else if (speed >= 8 && speed <= 10 && headingVariance > 30) {
    // 선망(PS) 포위 단계: 8~10kn + 원형 궤적
    gearType = 'purse_seine';
    isOperating = true;
    operatingStatusKo = '선망 포위 중 (8~10kn 원형)';
    confidence = 0.94;

  } else if (speed <= 3 && headingVariance > 40) {
    // 선망(PS) 죔줄 단계: 3kn 이하 + 이전 고속→저속 급전환
    gearType = 'purse_seine';
    isOperating = true;
    operatingStatusKo = '선망 죔줄 조임 중 (<3kn)';
    confidence = 0.85;

  } else if (speed >= 2 && speed <= 5 && headingVariance < 30) {
    // 트롤(PT/OT): 2~5kn + 완만한 방향 (Lawn-mowing)
    gearType = headingVariance < 15 ? 'trawl_pair' : 'trawl_single';
    isOperating = true;
    operatingStatusKo = `트롤 예인 중 (${speed.toFixed(1)}kn 지그재그)`;
    confidence = headingVariance < 15 ? 0.92 : 0.89;

  } else if (speed < 2) {
    // 0~2kn 극저속 → 조업 중 or 정박 대기
    if (isAnchored || speed < 0.3) {
      // 완전 정지/정박 → 비조업 (대기 중)
      gearType = 'unknown';
      isOperating = false;
      operatingStatusKo = speed < 0.3 ? '정지/대기 중' : '정박 중';
      confidence = 0.7;
    } else if (speed >= 0.3 && speed < 1 && headingVariance < 8) {
      // 극저속 + 방향 변화 거의 없음 → 안강망 (조류 이용 수동 어구)
      gearType = 'stow_net';
      isOperating = true;
      operatingStatusKo = '안강망 조업 추정 (조류 이용)';
      confidence = 0.65;
    } else if (speed >= 0.3 && speed < 2) {
      // 저속 이동 → 자망 투망/양망
      gearType = 'gillnet';
      isOperating = true;
      operatingStatusKo = speed < 1 ? '자망 투하/대기 중' : '자망 양망 중 (극저속)';
      confidence = 0.72;
    }

  } else if (speed >= 5 && speed < 8) {
    // 중속 이동 → 조업지 이동 또는 운반선
    gearType = 'carrier';
    isOperating = false;
    operatingStatusKo = '이동 중 (조업지 이동 추정)';
    confidence = 0.5;
  }

  // === 위반 위험도 판별 (보고서 5장 기반) ===
  const now = new Date();
  const meta = GEAR_META[gearType];
  let riskLevel: FishingAnalysis['riskLevel'] = 'LOW';
  let riskReason = '정상 범위';

  // 휴어기 체크
  if (meta.permitCode !== '-' && !isInPermitPeriod(meta.permitCode, now)) {
    riskLevel = 'CRITICAL';
    riskReason = `휴어기 조업 의심 (${meta.permitCode} 허가기간: ${PERMIT_PERIODS[meta.permitCode]?.label})`;
  }

  // AIS 신호 오래된 경우 (다크베셀 의심)
  const aisAge = Date.now() - ship.lastSeen;
  if (aisAge > 6 * 3600_000) {
    riskLevel = 'HIGH';
    riskReason = `AIS 공백 ${Math.round(aisAge / 3600_000)}시간 — 다크베셀 의심`;
  }

  // 자망 + 조업 중 → AIS 차단 가능성 높음
  if (gearType === 'gillnet' && isOperating) {
    if (riskLevel === 'LOW') {
      riskLevel = 'MEDIUM';
      riskReason = '유자망 조업 중 — AIS 차단 주의 업종';
    }
  }

  return {
    gearType,
    gearTypeKo: meta.ko,
    permitCode: meta.permitCode,
    gbCode: meta.gbCode,
    isOperating,
    operatingStatusKo,
    confidence,
    riskLevel,
    riskReason,
  };
}

/**
 * 중국 어선 조업 통계 집계
 */
export function aggregateFishingStats(ships: Ship[]) {
  // 중국 어선(fishing 카테고리)만 대상
  const chineseFishing = ships.filter(s => s.flag === 'CN' && s.category === 'fishing');
  const results = chineseFishing.map(s => ({ ship: s, analysis: analyzeFishing(s) }));

  const operating = results.filter(r => r.analysis.isOperating);
  const byGear: Record<FishingGearType, number> = {
    trawl_pair: 0, trawl_single: 0, gillnet: 0, stow_net: 0, purse_seine: 0, carrier: 0, unknown: 0,
  };
  for (const r of operating) {
    byGear[r.analysis.gearType]++;
  }

  const critical = results.filter(r => r.analysis.riskLevel === 'CRITICAL').length;
  const high = results.filter(r => r.analysis.riskLevel === 'HIGH').length;

  return {
    total: chineseFishing.length,
    operating: operating.length,
    idle: chineseFishing.length - operating.length,
    byGear,
    critical,
    high,
    details: results,
  };
}
