/**
 * 다크베셀 탐지 패턴 카탈로그
 *
 * SSOT: backend dark_pattern enum (V008 시드 DARK_PATTERN 그룹)
 * 사용처: DarkVesselDetection
 */

import type { BadgeIntent } from '@lib/theme/variants';

export type DarkVesselPattern =
  | 'AIS_FULL_BLOCK'      // AIS 완전차단
  | 'MMSI_SPOOFING'       // MMSI 변조 의심
  | 'LONG_LOSS'           // 장기소실
  | 'INTERMITTENT'        // 신호 간헐송출
  | 'SPEED_ANOMALY';      // 속도 이상

interface DarkVesselPatternMeta {
  code: DarkVesselPattern;
  i18nKey: string;
  fallback: { ko: string; en: string };
  intent: BadgeIntent;
  hex: string;
}

export const DARK_VESSEL_PATTERNS: Record<DarkVesselPattern, DarkVesselPatternMeta> = {
  AIS_FULL_BLOCK: {
    code: 'AIS_FULL_BLOCK',
    i18nKey: 'darkPattern.AIS_FULL_BLOCK',
    fallback: { ko: 'AIS 완전차단', en: 'AIS Full Block' },
    intent: 'critical',
    hex: '#ef4444',
  },
  MMSI_SPOOFING: {
    code: 'MMSI_SPOOFING',
    i18nKey: 'darkPattern.MMSI_SPOOFING',
    fallback: { ko: 'MMSI 변조 의심', en: 'MMSI Spoofing' },
    intent: 'high',
    hex: '#f97316',
  },
  LONG_LOSS: {
    code: 'LONG_LOSS',
    i18nKey: 'darkPattern.LONG_LOSS',
    fallback: { ko: '장기 소실', en: 'Long Loss' },
    intent: 'warning',
    hex: '#eab308',
  },
  INTERMITTENT: {
    code: 'INTERMITTENT',
    i18nKey: 'darkPattern.INTERMITTENT',
    fallback: { ko: '신호 간헐송출', en: 'Intermittent' },
    intent: 'purple',
    hex: '#a855f7',
  },
  SPEED_ANOMALY: {
    code: 'SPEED_ANOMALY',
    i18nKey: 'darkPattern.SPEED_ANOMALY',
    fallback: { ko: '속도 이상', en: 'Speed Anomaly' },
    intent: 'cyan',
    hex: '#06b6d4',
  },
};

/** 한글 라벨 호환 매핑 (mock 데이터에 한글이 들어있어서) */
const LEGACY_KO: Record<string, DarkVesselPattern> = {
  'AIS 완전차단': 'AIS_FULL_BLOCK',
  'MMSI 변조 의심': 'MMSI_SPOOFING',
  '장기소실': 'LONG_LOSS',
  '장기 소실': 'LONG_LOSS',
  '신호 간헐송출': 'INTERMITTENT',
  '속도 이상': 'SPEED_ANOMALY',
};

export function getDarkVesselPatternMeta(p: string): DarkVesselPatternMeta | undefined {
  if (DARK_VESSEL_PATTERNS[p as DarkVesselPattern]) return DARK_VESSEL_PATTERNS[p as DarkVesselPattern];
  const code = LEGACY_KO[p];
  return code ? DARK_VESSEL_PATTERNS[code] : undefined;
}

export function getDarkVesselPatternIntent(p: string): BadgeIntent {
  return getDarkVesselPatternMeta(p)?.intent ?? 'muted';
}

export function getDarkVesselPatternLabel(
  p: string,
  t: (k: string, opts?: { defaultValue?: string }) => string,
  lang: 'ko' | 'en' = 'ko',
): string {
  const meta = getDarkVesselPatternMeta(p);
  if (!meta) return p;
  return t(meta.i18nKey, { defaultValue: meta.fallback[lang] });
}

// ─── prediction 실제 판정 패턴 (dark_vessel.py P1~P11) ──────────
// features.dark_patterns 배열에 저장되는 코드 → 한국어 라벨 + 점수 매핑

export interface ScoringPatternMeta {
  label: string;
  labelEn: string;
  score: number;       // 양수=가점, 음수=감점
  scoreLabel: string;  // "+25" / "-50"
  desc: string;
  descEn: string;
  intent: BadgeIntent;
  category: 'movement' | 'zone' | 'history' | 'identity' | 'signal' | 'coverage';
}

export const DARK_SCORING_PATTERNS: Record<string, ScoringPatternMeta> = {
  // P1: 이동 상태
  moving_at_off:           { label: '이동중 OFF', labelEn: 'Moving at OFF', score: 25, scoreLabel: '+25', desc: 'SOG > 5kn에서 AIS 꺼짐', descEn: 'AIS off while SOG > 5kn', intent: 'critical', category: 'movement' },
  slow_moving_at_off:      { label: '저속 이동중 OFF', labelEn: 'Slow moving at OFF', score: 15, scoreLabel: '+15', desc: 'SOG 2~5kn에서 AIS 꺼짐', descEn: 'AIS off while SOG 2~5kn', intent: 'high', category: 'movement' },
  // P2: 수역
  sensitive_zone:          { label: '민감 수역', labelEn: 'Sensitive zone', score: 25, scoreLabel: '+25', desc: '영해/접속수역에서 gap 시작', descEn: 'Gap started in territorial/contiguous zone', intent: 'critical', category: 'zone' },
  special_zone:            { label: '특정수역', labelEn: 'Special zone', score: 15, scoreLabel: '+15', desc: '특정어업수역에서 gap 시작', descEn: 'Gap started in special fishing zone', intent: 'high', category: 'zone' },
  // P3: 반복 이력
  repeat_high:             { label: '반복 dark (고)', labelEn: 'Repeat dark (high)', score: 30, scoreLabel: '+30', desc: '7일내 3일+ dark 이력', descEn: '3+ dark days in 7 days', intent: 'critical', category: 'history' },
  repeat_low:              { label: '반복 dark (저)', labelEn: 'Repeat dark (low)', score: 15, scoreLabel: '+15', desc: '7일내 2일 dark 이력', descEn: '2 dark days in 7 days', intent: 'warning', category: 'history' },
  recent_dark:             { label: '최근 dark', labelEn: 'Recent dark', score: 10, scoreLabel: '+10', desc: '24시간내 dark 이력', descEn: 'Dark within 24h', intent: 'warning', category: 'history' },
  // P4: 이동거리
  distance_anomaly:        { label: '이동거리 이상', labelEn: 'Distance anomaly', score: 20, scoreLabel: '+20', desc: 'gap 중 예상 대비 2배+ 이동', descEn: 'Moved 2x+ expected during gap', intent: 'high', category: 'movement' },
  // P5: 조업 시간
  daytime_fishing_off:     { label: '주간 조업중 OFF', labelEn: 'Daytime fishing OFF', score: 15, scoreLabel: '+15', desc: '06~18시 조업 중 AIS 꺼짐', descEn: 'AIS off while fishing 06-18h', intent: 'high', category: 'movement' },
  // P6: 이상 행동
  teleport_before_gap:     { label: 'gap 전 텔레포트', labelEn: 'Teleport before gap', score: 15, scoreLabel: '+15', desc: 'gap 직전 위치 점프', descEn: 'Position jump before gap', intent: 'high', category: 'signal' },
  // P7: 무허가
  unpermitted:             { label: '무허가', labelEn: 'Unpermitted', score: 10, scoreLabel: '+10', desc: '허가 목록 미등록 선박', descEn: 'Not in permit registry', intent: 'warning', category: 'identity' },
  // P8: gap 길이
  very_long_gap:           { label: '장기 gap (6h+)', labelEn: 'Very long gap (6h+)', score: 15, scoreLabel: '+15', desc: '360분 이상 gap', descEn: 'Gap >= 360min', intent: 'high', category: 'signal' },
  long_gap:                { label: 'gap (3h+)', labelEn: 'Long gap (3h+)', score: 10, scoreLabel: '+10', desc: '180분 이상 gap', descEn: 'Gap >= 180min', intent: 'warning', category: 'signal' },
  // P9: 선종 (signal-batch 보강)
  fishing_vessel_dark:     { label: '어선 dark', labelEn: 'Fishing vessel dark', score: 10, scoreLabel: '+10', desc: '어선(000020)의 의도적 OFF 가능성', descEn: 'Fishing vessel intentional OFF', intent: 'warning', category: 'identity' },
  cargo_natural_gap:       { label: '화물선 자연 gap', labelEn: 'Cargo natural gap', score: -10, scoreLabel: '-10', desc: '화물선 원양 항해 자연 gap', descEn: 'Cargo vessel ocean gap (natural)', intent: 'info', category: 'identity' },
  // P10: 항해 상태
  underway_deliberate_off: { label: '항행중 의도적 OFF', labelEn: 'Underway deliberate OFF', score: 20, scoreLabel: '+20', desc: '항행 상태에서 갑자기 OFF', descEn: 'AIS off while under way', intent: 'critical', category: 'movement' },
  anchored_natural_gap:    { label: '정박중 자연 gap', labelEn: 'Anchored natural gap', score: -15, scoreLabel: '-15', desc: '정박/계류 중 gap은 자연스러움', descEn: 'Gap while anchored/moored (natural)', intent: 'info', category: 'movement' },
  // P11: heading/COG
  heading_cog_mismatch:    { label: '방향 불일치', labelEn: 'Heading/COG mismatch', score: 15, scoreLabel: '+15', desc: '선수방향과 침로 60°+ 차이', descEn: 'Heading vs COG diff > 60°', intent: 'high', category: 'signal' },
  // 감점
  out_of_coverage:         { label: '커버리지 밖', labelEn: 'Out of coverage', score: -50, scoreLabel: '-50', desc: 'AIS 수신범위 외 → 자연 gap', descEn: 'Outside AIS coverage → natural gap', intent: 'muted', category: 'coverage' },
};

/** prediction dark_patterns 코드로 scoring 메타 조회 */
export function getScoringPatternMeta(code: string): ScoringPatternMeta | undefined {
  return DARK_SCORING_PATTERNS[code];
}

/** dark_patterns 배열 → 점수 내역 (가점/감점 분리) */
export function buildScoreBreakdown(patterns: string[]): {
  items: (ScoringPatternMeta & { code: string })[];
  totalAdd: number;
  totalSub: number;
  rawTotal: number;
} {
  const items = patterns
    .map(code => {
      const meta = DARK_SCORING_PATTERNS[code];
      return meta ? { ...meta, code } : null;
    })
    .filter((v): v is ScoringPatternMeta & { code: string } => v !== null)
    .sort((a, b) => b.score - a.score);

  const totalAdd = items.filter(i => i.score > 0).reduce((s, i) => s + i.score, 0);
  const totalSub = items.filter(i => i.score < 0).reduce((s, i) => s + i.score, 0);
  return { items, totalAdd, totalSub, rawTotal: totalAdd + totalSub };
}
