import { useState, useRef, useCallback } from 'react';
import { BaseMap, createStaticLayers, createMarkerLayer, createRadiusLayer, useMapLayers, type MapHandle } from '@lib/map';
import { Card, CardContent } from '@shared/components/ui/card';
import { Badge } from '@shared/components/ui/badge';
import { PageContainer, PageHeader } from '@shared/components/layout';
import { DataTable, type DataColumn } from '@shared/components/common/DataTable';
import { Map, Shield, Crosshair, AlertTriangle, Eye, Anchor, Ship, Filter, Layers, Target, Clock, MapPin, Bell, Navigation, Info } from 'lucide-react';
import { getTrainingZoneIntent, getTrainingZoneHex, getTrainingZoneMeta } from '@shared/constants/trainingZoneTypes';
import type { BadgeIntent } from '@lib/theme/variants';

/*
 * 해역 통제 — 한국연안 해상사격 훈련구역도 (No.462) 반영
 * Chart of Firing and Bombing Exercise Areas in the Coasts of Korea
 * 출처: 국립해양조사원 (WGS-84)
 *
 * 구역 분류:
 *  - 해군 훈련 구역 (노란색)
 *  - 공군 훈련 구역 (분홍색)
 *  - 육군 훈련 구역 (초록색)
 *  - 국방과학연구소 훈련구역 (파란색)
 *  - 해양경찰청 훈련구역 (보라색)
 */

type Tab = 'overview' | 'navy' | 'airforce' | 'army' | 'add' | 'kcg' | 'ntm';

// ─── 훈련구역 데이터 ──────────────────────

interface TrainingZone {
  id: string;
  name: string;
  type: string;
  sea: string;
  lat: string;
  lng: string;
  radius: string;
  status: string;
  schedule: string;
  note: string;
  [key: string]: unknown;
}

const NAVY_ZONES: TrainingZone[] = [
  { id: 'R-77', name: 'R-77', type: '해군', sea: '동해', lat: '38°20\'N', lng: '128°40\'E', radius: '20NM', status: '활성', schedule: '수시', note: '동해 북부 사격' },
  { id: 'R-80', name: 'R-80', type: '해군', sea: '서해', lat: '35°10\'N', lng: '125°30\'E', radius: '30NM', status: '활성', schedule: '수시', note: '서해 중부 사격' },
  { id: 'R-84', name: 'R-84', type: '해군', sea: '서해', lat: '34°00\'N~33°00\'N', lng: '125°00\'E~126°00\'E', radius: '대형', status: '활성', schedule: '수시', note: '서해 남부 대규모 사격구역' },
  { id: 'R-88', name: 'R-88', type: '해군', sea: '서해', lat: '35°30\'N', lng: '125°00\'E', radius: '15NM', status: '활성', schedule: '수시', note: '서해 황해 사격' },
  { id: 'R-99', name: 'R-99', type: '해군', sea: '남해', lat: '34°50\'N', lng: '128°40\'E', radius: '10NM', status: '활성', schedule: '주간', note: '남해 동부' },
  { id: 'R-100', name: 'R-100', type: '해군', sea: '남해', lat: '35°00\'N', lng: '129°10\'E', radius: '8NM', status: '활성', schedule: '주간', note: '부산 근해' },
  { id: 'R-104', name: 'R-104', type: '해군', sea: '서해', lat: '34°30\'N', lng: '125°20\'E', radius: '12NM', status: '활성', schedule: '수시', note: '고군산군도' },
  { id: 'R-105', name: 'R-105', type: '해군', sea: '서해', lat: '34°40\'N', lng: '125°10\'E', radius: '10NM', status: '활성', schedule: '수시', note: '서해 남서' },
  { id: 'R-107', name: 'R-107', type: '해군', sea: '동해', lat: '38°10\'N', lng: '129°50\'E', radius: '15NM', status: '활성', schedule: '수시', note: '동해 북부' },
  { id: 'R-115', name: 'R-115', type: '해군', sea: '동해', lat: '37°30\'N', lng: '130°00\'E', radius: '12NM', status: '활성', schedule: '주간', note: '동해 중부' },
  { id: 'R-117', name: 'R-117', type: '해군', sea: '남해', lat: '34°30\'N', lng: '127°30\'E', radius: '10NM', status: '비활성', schedule: '-', note: '여수 근해' },
  { id: 'R-118', name: 'R-118', type: '해군', sea: '남해', lat: '33°50\'N', lng: '128°20\'E', radius: '15NM', status: '활성', schedule: '수시', note: '남해 외해' },
  { id: 'R-119', name: 'R-119', type: '해군', sea: '동해', lat: '36°10\'N', lng: '129°40\'E', radius: '8NM', status: '활성', schedule: '야간', note: '울진 근해' },
  { id: 'R-120', name: 'R-120', type: '해군', sea: '동해', lat: '36°30\'N', lng: '130°10\'E', radius: '20NM', status: '활성', schedule: '수시', note: '동해 중부 외해' },
];

const AIR_ZONES: TrainingZone[] = [
  { id: 'R-108A', name: 'R-108A', type: '공군', sea: '서해', lat: '38°30\'N', lng: '124°30\'E', radius: '대형', status: '활성', schedule: '수시', note: '서해 북부 공중사격' },
  { id: 'R-108B', name: 'R-108B', type: '공군', sea: '서해', lat: '38°10\'N', lng: '124°20\'E', radius: '대형', status: '활성', schedule: '수시', note: '서해 북부' },
  { id: 'R-108C', name: 'R-108C', type: '공군', sea: '서해', lat: '37°00\'N', lng: '124°00\'E', radius: '대형', status: '활성', schedule: '수시', note: '서해 중부' },
  { id: 'R-108D', name: 'R-108D', type: '공군', sea: '서해', lat: '38°00\'N', lng: '124°50\'E', radius: '중형', status: '활성', schedule: '주간', note: '백령도 인근' },
  { id: 'R-108E', name: 'R-108E', type: '공군', sea: '서해', lat: '38°05\'N', lng: '124°40\'E', radius: '중형', status: '활성', schedule: '주간', note: '대청도 인근' },
  { id: 'R-108F', name: 'R-108F', type: '공군', sea: '서해', lat: '37°50\'N', lng: '124°30\'E', radius: '중형', status: '활성', schedule: '수시', note: '서해 5도' },
  { id: 'R-123', name: 'R-123', type: '공군', sea: '남해', lat: '34°20\'N', lng: '126°00\'E', radius: '15NM', status: '활성', schedule: '수시', note: '진도 남방' },
  { id: 'R-124', name: 'R-124', type: '공군', sea: '서해', lat: '35°40\'N', lng: '125°40\'E', radius: '10NM', status: '활성', schedule: '주간', note: '군산 서방' },
];

const ARMY_ZONES: TrainingZone[] = [
  { id: 'R-97A', name: 'R-97A', type: '육군', sea: '서해', lat: '34°20\'N', lng: '125°40\'E', radius: '5NM', status: '활성', schedule: '주간', note: '서해안 포사격' },
  { id: 'R-97B', name: 'R-97B', type: '육군', sea: '서해', lat: '34°25\'N', lng: '125°35\'E', radius: '5NM', status: '활성', schedule: '주간', note: '서해안 포사격' },
  { id: 'R-97C', name: 'R-97C', type: '육군', sea: '서해', lat: '34°00\'N', lng: '125°20\'E', radius: '8NM', status: '활성', schedule: '수시', note: '서해 남부' },
  { id: 'R-97D', name: 'R-97D', type: '육군', sea: '서해', lat: '34°05\'N', lng: '125°15\'E', radius: '5NM', status: '비활성', schedule: '-', note: '서해 남부' },
  { id: 'R-97E', name: 'R-97E', type: '육군', sea: '서해', lat: '34°30\'N', lng: '125°50\'E', radius: '5NM', status: '활성', schedule: '주간', note: '고군산 인근' },
  { id: 'R-97F', name: 'R-97F', type: '육군', sea: '서해', lat: '34°35\'N', lng: '125°45\'E', radius: '5NM', status: '활성', schedule: '주간', note: '서해안 포사격' },
];

const ADD_ZONES: TrainingZone[] = [
  { id: 'R-121', name: 'R-121', type: '국과연', sea: '동해', lat: '38°20\'N', lng: '128°50\'E', radius: '대형', status: '활성', schedule: '수시', note: '국방과학연구소 시험구역' },
  { id: 'R-125', name: 'R-125', type: '국과연', sea: '남해', lat: '34°20\'N', lng: '127°20\'E', radius: '10NM', status: '활성', schedule: '수시', note: '남해 시험' },
  { id: 'R-126', name: 'R-126', type: '국과연', sea: '제주', lat: '33°40\'N', lng: '126°30\'E', radius: '15NM', status: '활성', schedule: '수시', note: '제주 해협' },
  { id: 'R-128', name: 'R-128', type: '국과연', sea: '남해', lat: '32°50\'N', lng: '127°00\'E', radius: '대형', status: '활성', schedule: '수시', note: '남해 외해 시험' },
];

const KCG_ZONES: TrainingZone[] = [
  { id: 'R-131', name: 'R-131', type: '해경', sea: '서해', lat: '37°40\'N', lng: '125°20\'E', radius: '5NM', status: '활성', schedule: '주간', note: '해경 서해 훈련' },
  { id: 'R-132', name: 'R-132', type: '해경', sea: '서해', lat: '37°30\'N', lng: '125°50\'E', radius: '5NM', status: '활성', schedule: '주간', note: '해경 인천 훈련' },
  { id: 'R-133', name: 'R-133', type: '해경', sea: '남해', lat: '35°20\'N', lng: '126°20\'E', radius: '3NM', status: '활성', schedule: '주간', note: '해경 남해 훈련' },
  { id: 'R-134', name: 'R-134', type: '해경', sea: '남해', lat: '35°50\'N', lng: '125°50\'E', radius: '3NM', status: '활성', schedule: '주간', note: '해경 서남해' },
];

const ALL_ZONES = [...NAVY_ZONES, ...AIR_ZONES, ...ARMY_ZONES, ...ADD_ZONES, ...KCG_ZONES];

// ─── 항행통보 데이터 (국립해양조사원 NtM) ──────

interface NtmRecord {
  no: string;
  date: string;
  category: string;
  sea: string;
  title: string;
  position: string;
  status: string;
  detail: string;
  [key: string]: unknown;
}

const NTM_DATA: NtmRecord[] = [
  { no: 'NTM-2026-0412', date: '2026-04-03', category: '사격훈련', sea: '서해', title: '서해 R-84 구역 사격훈련 실시', position: 'N34°00\' E125°30\'', status: '발령중', detail: '04-03 09:00~18:00 실탄사격 실시. 선박 진입 금지.' },
  { no: 'NTM-2026-0411', date: '2026-04-03', category: '사격훈련', sea: '동해', title: '동해 R-120 구역 해군 사격', position: 'N36°30\' E130°10\'', status: '발령중', detail: '04-03~04-05 종일 사격훈련. 반경 20NM 진입금지.' },
  { no: 'NTM-2026-0410', date: '2026-04-02', category: '기뢰제거', sea: '남해', title: '여수항 인근 기뢰 제거 작업', position: 'N34°44\' E127°46\'', status: '발령중', detail: '04-02~04-06 기뢰 탐색 및 제거. 반경 3NM 항행주의.' },
  { no: 'NTM-2026-0409', date: '2026-04-02', category: '해양공사', sea: '남해', title: '부산 신항 준설작업', position: 'N35°04\' E128°49\'', status: '발령중', detail: '04-01~04-30 야간 준설. 항행선박 감속 운항.' },
  { no: 'NTM-2026-0408', date: '2026-04-01', category: '항로표지', sea: '서해', title: '인천항 서수도 등부표 소등', position: 'N37°26\' E126°34\'', status: '발령중', detail: '등부표 고장으로 소등 중. 수리 완료 시까지 항행주의.' },
  { no: 'NTM-2026-0407', date: '2026-04-01', category: '사격훈련', sea: '서해', title: '서해 R-80 공군 폭격훈련', position: 'N35°10\' E125°30\'', status: '해제', detail: '04-01 훈련 완료. 해제됨.' },
  { no: 'NTM-2026-0406', date: '2026-03-31', category: '해양오염', sea: '남해', title: '통영 해역 유류유출 경보', position: 'N34°50\' E128°25\'', status: '해제', detail: '방제 완료. 03-31 18:00 해제.' },
  { no: 'NTM-2026-0405', date: '2026-03-30', category: '수중작업', sea: '동해', title: '포항 해저케이블 설치', position: 'N36°02\' E129°24\'', status: '발령중', detail: '03-28~04-15 해저케이블 부설. 닻 투하 금지.' },
  { no: 'NTM-2026-0404', date: '2026-03-29', category: '사격훈련', sea: '동해', title: '동해 R-77 해군 사격', position: 'N38°20\' E128°40\'', status: '해제', detail: '03-29 훈련 완료.' },
  { no: 'NTM-2026-0403', date: '2026-03-28', category: '항로변경', sea: '서해', title: '평택항 입항항로 임시변경', position: 'N36°58\' E126°49\'', status: '발령중', detail: '항로 표지 공사로 임시 우회항로 지정 (~04-10).' },
  { no: 'NTM-2026-0402', date: '2026-03-27', category: '군사훈련', sea: '서해', title: '서해 R-108A 공군 훈련', position: 'N38°30\' E124°30\'', status: '해제', detail: '03-27 훈련 완료.' },
  { no: 'NTM-2026-0401', date: '2026-03-25', category: '사격훈련', sea: '서해', title: '서해 5도 해역 경비함정 훈련', position: 'N37°45\' E124°50\'', status: '해제', detail: '해경 해상사격 완료.' },
];

const NTM_CATEGORIES = ['전체', '사격훈련', '군사훈련', '기뢰제거', '해양공사', '항로표지', '항로변경', '해양오염', '수중작업'];

const ntmColumns: DataColumn<NtmRecord>[] = [
  { key: 'no', label: '통보번호', width: '120px', sortable: true, render: v => <span className="text-cyan-400 font-mono font-bold text-[10px]">{v as string}</span> },
  { key: 'date', label: '발령일', width: '90px', sortable: true, render: v => <span className="text-muted-foreground font-mono text-[10px]">{v as string}</span> },
  { key: 'category', label: '구분', width: '70px', align: 'center', sortable: true,
    render: v => {
      const c = v as string;
      const intent: BadgeIntent = c.includes('사격') || c.includes('군사') ? 'critical'
        : c.includes('기뢰') ? 'high'
        : c.includes('오염') ? 'warning'
        : 'info';
      return <Badge intent={intent} size="xs">{c}</Badge>;
    },
  },
  { key: 'sea', label: '해역', width: '50px', sortable: true },
  { key: 'title', label: '제목', sortable: true, render: v => <span className="text-heading font-medium">{v as string}</span> },
  { key: 'position', label: '위치', width: '120px', render: v => <span className="text-muted-foreground font-mono text-[10px]">{v as string}</span> },
  { key: 'status', label: '상태', width: '70px', align: 'center', sortable: true,
    render: v => <Badge intent={v === '발령중' ? 'critical' : 'muted'} size="xs">{v as string}</Badge> },
];

// 훈련구역 색상은 trainingZoneTypes 카탈로그에서 lookup

const columns: DataColumn<TrainingZone>[] = [
  { key: 'id', label: '구역번호', width: '80px', sortable: true, render: v => <span className="text-cyan-400 font-mono font-bold">{v as string}</span> },
  { key: 'type', label: '구분', width: '60px', align: 'center', sortable: true,
    render: v => <Badge intent={getTrainingZoneIntent(v as string)} size="sm">{v as string}</Badge> },
  { key: 'sea', label: '해역', width: '60px', sortable: true },
  { key: 'lat', label: '위도', width: '110px', render: v => <span className="text-muted-foreground font-mono text-[10px]">{v as string}</span> },
  { key: 'lng', label: '경도', width: '110px', render: v => <span className="text-muted-foreground font-mono text-[10px]">{v as string}</span> },
  { key: 'radius', label: '반경', width: '60px', align: 'center' },
  { key: 'status', label: '상태', width: '60px', align: 'center', sortable: true,
    render: v => <Badge intent={v === '활성' ? 'success' : 'muted'} size="xs">{v as string}</Badge> },
  { key: 'schedule', label: '운용', width: '60px', align: 'center' },
  { key: 'note', label: '비고', render: v => <span className="text-hint">{v as string}</span> },
];

// DMS 좌표 → 십진수 변환
function parseDMS(dms: string): number | null {
  // "38°20'N" → 38.333...  /  "34°00'N~33°00'N" → 중간값
  if (dms.includes('~')) {
    const parts = dms.split('~');
    const a = parseDMS(parts[0]);
    const b = parseDMS(parts[1]);
    if (a !== null && b !== null) return (a + b) / 2;
    return a;
  }
  const m = dms.match(/(\d+)°(\d+)?'?([NSEW])?/);
  if (!m) return null;
  let val = parseInt(m[1]) + (parseInt(m[2] || '0') / 60);
  if (m[3] === 'S' || m[3] === 'W') val = -val;
  return val;
}

// 반경 문자열 → 미터 변환 (1NM ≈ 1852m)
function parseRadius(r: string): number {
  const nm = r.match(/(\d+)\s*NM/i);
  if (nm) return parseInt(nm[1]) * 1852;
  if (r === '대형') return 40000;
  if (r === '중형') return 25000;
  return 15000;
}


export function MapControl() {
  const mapRef = useRef<MapHandle>(null);
  const [tab, setTab] = useState<Tab>('overview');
  const [seaFilter, setSeaFilter] = useState('');
  const [ntmCatFilter, setNtmCatFilter] = useState('');

  const getZones = () => {
    const zones = tab === 'navy' ? NAVY_ZONES : tab === 'airforce' ? AIR_ZONES : tab === 'army' ? ARMY_ZONES : tab === 'add' ? ADD_ZONES : tab === 'kcg' ? KCG_ZONES : ALL_ZONES;
    return seaFilter ? zones.filter(z => z.sea === seaFilter) : zones;
  };

  const activeCount = ALL_ZONES.filter(z => z.status === '활성').length;

  // 현재 표시할 구역
  const visibleZones = getZones();

  const buildLayers = useCallback(() => {
    // 훈련구역 원 + 중심 마커
    const parsedZones: { lat: number; lng: number; color: string; radiusM: number; isActive: boolean; zone: TrainingZone }[] = [];
    visibleZones.forEach((z) => {
      const lat = parseDMS(z.lat);
      const lng = parseDMS(z.lng);
      if (lat === null || lng === null) return;
      const color = getTrainingZoneHex(z.type);
      const radiusM = parseRadius(z.radius);
      const isActive = z.status === '활성';
      parsedZones.push({ lat, lng, color, radiusM, isActive, zone: z });
    });

    // 활성/비활성 구역을 opacity별로 분리
    const activeZones = parsedZones.filter(pz => pz.isActive);
    const inactiveZones = parsedZones.filter(pz => !pz.isActive);

    // 중심점 마커
    const centerMarkers = parsedZones.map((pz) => ({
      lat: pz.lat,
      lng: pz.lng,
      color: pz.color,
      radius: 600,
      label: pz.zone.id,
    }));

    return [
      ...createStaticLayers(),
      createRadiusLayer(
        'zone-circles-active',
        activeZones.map(pz => ({ lat: pz.lat, lng: pz.lng, radius: pz.radiusM, color: pz.color })),
        0.15,
      ),
      createRadiusLayer(
        'zone-circles-inactive',
        inactiveZones.map(pz => ({ lat: pz.lat, lng: pz.lng, radius: pz.radiusM, color: pz.color })),
        0.05,
      ),
      createMarkerLayer('zone-centers', centerMarkers),
    ];
  }, [visibleZones]);
  useMapLayers(mapRef, buildLayers, [visibleZones]);

  return (
    <PageContainer>
      <PageHeader
        icon={Map}
        iconColor="text-cyan-400"
        title="해역 통제"
        description="한국연안 해상사격 훈련구역도 No.462 | Chart of Firing and Bombing Exercise Areas | WGS-84 | 출처: 국립해양조사원"
        demo
      />

      {/* KPI */}
      <div className="flex gap-2">
        {[
          { label: '전체 구역', value: ALL_ZONES.length, color: 'text-heading' },
          { label: '활성', value: activeCount, color: 'text-green-400' },
          { label: '해군', value: NAVY_ZONES.length, color: 'text-yellow-400' },
          { label: '공군', value: AIR_ZONES.length, color: 'text-pink-400' },
          { label: '육군', value: ARMY_ZONES.length, color: 'text-green-400' },
          { label: '국과연', value: ADD_ZONES.length, color: 'text-blue-400' },
          { label: '해경', value: KCG_ZONES.length, color: 'text-purple-400' },
        ].map(k => (
          <div key={k.label} className="flex-1 flex items-center gap-2 px-3 py-2 rounded-xl border border-border bg-card">
            <span className={`text-base font-bold ${k.color}`}>{k.value}</span>
            <span className="text-[9px] text-hint">{k.label}</span>
          </div>
        ))}
      </div>

      {/* 범례 */}
      <div className="flex items-center gap-4 px-4 py-2 rounded-xl border border-border bg-card">
        <span className="text-[10px] text-hint font-bold">범례:</span>
        {(['해군', '공군', '육군', '국과연', '해경'] as const).map((type) => {
          const meta = getTrainingZoneMeta(type);
          if (!meta) return null;
          return (
            <div key={type} className="flex items-center gap-1.5">
              <div className="w-4 h-3 rounded-sm" style={{ backgroundColor: meta.hex, opacity: 0.6 }} />
              <span className="text-[10px] text-muted-foreground">{meta.fallback.ko}</span>
            </div>
          );
        })}
      </div>

      {/* 탭 + 해역 필터 */}
      <div className="flex items-center gap-3">
        <div className="flex gap-0 border-b border-border">
          {([
            { key: 'overview' as Tab, label: '전체', icon: Layers },
            { key: 'navy' as Tab, label: '해군', icon: Ship },
            { key: 'airforce' as Tab, label: '공군', icon: Target },
            { key: 'army' as Tab, label: '육군', icon: Crosshair },
            { key: 'add' as Tab, label: '국과연', icon: Shield },
            { key: 'kcg' as Tab, label: '해경', icon: Anchor },
            { key: 'ntm' as Tab, label: '항행통보', icon: Bell },
          ]).map(t => (
            <button type="button" key={t.key} onClick={() => setTab(t.key)}
              className={`flex items-center gap-1.5 px-4 py-2 text-[11px] font-medium border-b-2 ${tab === t.key ? 'text-cyan-400 border-cyan-400' : 'text-hint border-transparent hover:text-label'}`}>
              <t.icon className="w-3.5 h-3.5" />{t.label}
            </button>
          ))}
        </div>
        <div className="flex items-center gap-1.5 ml-auto">
          <Filter className="w-3.5 h-3.5 text-hint" />
          {['', '서해', '남해', '동해', '제주'].map(s => (
            <button type="button" key={s} onClick={() => setSeaFilter(s)}
              className={`px-2.5 py-1 rounded text-[10px] ${seaFilter === s ? 'bg-cyan-600 text-on-vivid font-bold' : 'text-hint hover:bg-surface-overlay'}`}>
              {s || '전체'}
            </button>
          ))}
        </div>
      </div>

      {/* ── 항행통보 탭 ── */}
      {tab === 'ntm' && (
        <div className="space-y-3">
          {/* 항행통보 KPI */}
          <div className="flex gap-2">
            {[
              { label: '전체 통보', value: NTM_DATA.length, color: 'text-heading' },
              { label: '발령중', value: NTM_DATA.filter(n => n.status === '발령중').length, color: 'text-red-400' },
              { label: '해제', value: NTM_DATA.filter(n => n.status === '해제').length, color: 'text-muted-foreground' },
              { label: '사격훈련', value: NTM_DATA.filter(n => n.category.includes('사격')).length, color: 'text-orange-400' },
            ].map(k => (
              <div key={k.label} className="flex-1 flex items-center gap-2 px-3 py-2 rounded-xl border border-border bg-card">
                <span className={`text-base font-bold ${k.color}`}>{k.value}</span>
                <span className="text-[9px] text-hint">{k.label}</span>
              </div>
            ))}
          </div>

          {/* 카테고리 필터 */}
          <div className="flex items-center gap-1.5 px-4 py-2 rounded-xl border border-border bg-card">
            <Filter className="w-3.5 h-3.5 text-hint" />
            <span className="text-[10px] text-hint">구분:</span>
            {NTM_CATEGORIES.map(c => (
              <button type="button" key={c} onClick={() => setNtmCatFilter(c === '전체' ? '' : c)}
                className={`px-2.5 py-1 rounded text-[10px] ${(c === '전체' && !ntmCatFilter) || ntmCatFilter === c ? 'bg-cyan-600 text-on-vivid font-bold' : 'text-hint hover:bg-surface-overlay'}`}>{c}</button>
            ))}
          </div>

          {/* 최근 발령 중 통보 하이라이트 */}
          <Card><CardContent className="p-4">
            <div className="text-[12px] font-bold text-heading mb-3 flex items-center gap-1.5">
              <AlertTriangle className="w-4 h-4 text-red-400" />현재 발령 중 항행통보
            </div>
            <div className="space-y-2">
              {NTM_DATA.filter(n => n.status === '발령중').map(n => (
                <div key={n.no} className="flex items-start gap-3 px-3 py-2.5 bg-red-500/5 border border-red-500/10 rounded-lg">
                  <Badge intent="critical" size="sm" className="shrink-0 mt-0.5">{n.category}</Badge>
                  <div className="flex-1 min-w-0">
                    <div className="text-[11px] text-heading font-medium">{n.title}</div>
                    <div className="text-[10px] text-hint mt-0.5">{n.detail}</div>
                  </div>
                  <div className="text-right shrink-0">
                    <div className="text-[10px] text-muted-foreground font-mono">{n.position}</div>
                    <div className="text-[9px] text-hint mt-0.5">{n.date}</div>
                  </div>
                </div>
              ))}
            </div>
          </CardContent></Card>

          {/* 전체 통보 DataTable */}
          <DataTable
            data={ntmCatFilter ? NTM_DATA.filter(n => n.category === ntmCatFilter) : NTM_DATA}
            columns={ntmColumns}
            pageSize={10}
            searchPlaceholder="통보번호, 제목, 해역 검색..."
            searchKeys={['no', 'title', 'sea', 'category', 'position']}
            exportFilename="항행통보"
          />

          <div className="text-[9px] text-hint text-right">출처: 국립해양조사원 항행통보 (https://www.khoa.go.kr/nwb)</div>
        </div>
      )}

      {/* 훈련구역 시각화 맵 (간략) — ntm 탭이 아닐 때 */}
      {/* 훈련구역 (ntm 탭이 아닐 때만) */}
      {tab !== 'ntm' && (
        <>
          <Card>
            <CardContent className="p-0 relative">
              <BaseMap ref={mapRef} key={`${tab}-${seaFilter}`} center={[35.8, 127.5]} zoom={7} height={480} className="w-full rounded-lg overflow-hidden" />
              {/* 범례 오버레이 */}
              <div className="absolute bottom-3 left-3 z-[1000] bg-background/90 backdrop-blur-sm border border-border rounded-lg px-3 py-2">
                <div className="text-[9px] text-muted-foreground font-bold mb-1.5">훈련구역 범례</div>
                <div className="space-y-1">
                  {(['해군', '공군', '육군', '국과연', '해경'] as const).map((type) => {
                    const meta = getTrainingZoneMeta(type);
                    if (!meta) return null;
                    return (
                      <div key={type} className="flex items-center gap-1.5">
                        <div className="w-3 h-3 rounded-full border" style={{ backgroundColor: meta.hex, borderColor: meta.hex, opacity: 0.7 }} />
                        <span className="text-[9px] text-muted-foreground">{meta.fallback.ko}</span>
                      </div>
                    );
                  })}
                </div>
                <div className="flex items-center gap-3 mt-1.5 pt-1.5 border-t border-border">
                  <div className="flex items-center gap-1"><div className="w-4 h-0 border-t-2 border-dashed border-red-500/50" /><span className="text-[8px] text-hint">EEZ</span></div>
                  <div className="flex items-center gap-1"><div className="w-4 h-0 border-t-2 border-dashed border-orange-500/70" /><span className="text-[8px] text-hint">NLL</span></div>
                </div>
                <div className="text-[7px] text-hint mt-1">구역 클릭 시 상세정보 표시</div>
              </div>
              {/* 표시 구역 수 */}
              <div className="absolute top-3 left-3 z-[1000] bg-background/90 backdrop-blur-sm border border-border rounded-lg px-3 py-1.5">
                <span className="text-[10px] text-cyan-400 font-bold">{visibleZones.length}개</span>
                <span className="text-[9px] text-hint ml-1">훈련구역 표시 중</span>
              </div>
            </CardContent>
          </Card>
          <DataTable
            data={getZones()}
            columns={columns}
            pageSize={12}
            searchPlaceholder="구역번호, 해역, 비고 검색..."
            searchKeys={['id', 'name', 'sea', 'note', 'type']}
            exportFilename="해상사격훈련구역"
          />
        </>
      )}
    </PageContainer>
  );
}
