import { useState, useEffect, useMemo } from 'react'
import { Map, useControl } from '@vis.gl/react-maplibre'
import { MapboxOverlay } from '@deck.gl/mapbox'
import { ScatterplotLayer, PathLayer, TextLayer } from '@deck.gl/layers'
import type { StyleSpecification } from 'maplibre-gl'
import type { PickingInfo } from '@deck.gl/core'
import 'maplibre-gl/dist/maplibre-gl.css'

// ── 지도 스타일 ─────────────────────────────────────────
const BASE_STYLE: StyleSpecification = {
  version: 8,
  sources: {
    'carto-dark': {
      type: 'raster',
      tiles: [
        'https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
        'https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
        'https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
      ],
      tileSize: 256,
      attribution: '&copy; OSM &copy; CARTO',
    },
  },
  layers: [{ id: 'carto-dark-layer', type: 'raster', source: 'carto-dark' }],
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function DeckGLOverlay({ layers }: { layers: any[] }) {
  const overlay = useControl<MapboxOverlay>(() => new MapboxOverlay({ interleaved: true }))
  overlay.setProps({ layers })
  return null
}

// ── Mock 데이터 ─────────────────────────────────────────
interface DroneInfo {
  id: string
  name: string
  status: 'active' | 'returning' | 'standby' | 'charging'
  battery: number
  altitude: number
  speed: number
  sensor: string
  color: string
  lon: number
  lat: number
}

const drones: DroneInfo[] = [
  { id: 'D-01', name: 'DJI M300 #1', status: 'active', battery: 78, altitude: 150, speed: 12, sensor: '광학 4K', color: '#3b82f6', lon: 128.68, lat: 34.72 },
  { id: 'D-02', name: 'DJI M300 #2', status: 'active', battery: 65, altitude: 200, speed: 8, sensor: 'IR 열화상', color: '#ef4444', lon: 128.74, lat: 34.68 },
  { id: 'D-03', name: 'Mavic 3E', status: 'active', battery: 82, altitude: 120, speed: 15, sensor: '광학 4K', color: '#a855f7', lon: 128.88, lat: 34.60 },
  { id: 'D-04', name: 'DJI M30T', status: 'active', battery: 45, altitude: 180, speed: 10, sensor: '다중센서', color: '#22c55e', lon: 128.62, lat: 34.56 },
  { id: 'D-05', name: 'DJI M300 #3', status: 'returning', battery: 12, altitude: 80, speed: 18, sensor: '광학 4K', color: '#f97316', lon: 128.80, lat: 34.75 },
  { id: 'D-06', name: 'Mavic 3E #2', status: 'charging', battery: 35, altitude: 0, speed: 0, sensor: '광학 4K', color: '#6b7280', lon: 128.70, lat: 34.65 },
]

interface VesselInfo {
  name: string
  lon: number
  lat: number
  aisOff: boolean
}

const vessels: VesselInfo[] = [
  { name: '영풍호', lon: 128.72, lat: 34.74, aisOff: false },
  { name: '불명-A', lon: 128.82, lat: 34.65, aisOff: true },
  { name: '금성호', lon: 128.60, lat: 34.62, aisOff: false },
  { name: '불명-B', lon: 128.92, lat: 34.70, aisOff: true },
  { name: '태양호', lon: 128.66, lat: 34.58, aisOff: false },
]

interface ZoneInfo {
  id: string
  lon: number
  lat: number
  radius: number
  color: [number, number, number]
}

const searchZones: ZoneInfo[] = [
  { id: 'A', lon: 128.70, lat: 34.72, radius: 3000, color: [6, 182, 212] },
  { id: 'B', lon: 128.88, lat: 34.60, radius: 2500, color: [249, 115, 22] },
  { id: 'C', lon: 128.62, lat: 34.56, radius: 2000, color: [234, 179, 8] },
]

const oilSpill = { lon: 128.85, lat: 34.58 }
const hnsPoint = { lon: 128.58, lat: 34.52 }

interface AlertItem {
  time: string
  type: 'warning' | 'info' | 'danger'
  message: string
}

const alerts: AlertItem[] = [
  { time: '15:42', type: 'danger', message: 'D-05 배터리 부족 — 자동 복귀' },
  { time: '15:38', type: 'warning', message: '오염원 신규 탐지 (34.82°N)' },
  { time: '15:35', type: 'info', message: 'D-01~D-03 다시점 융합 완료' },
  { time: '15:30', type: 'warning', message: 'AIS OFF 선박 2척 추가 탐지' },
  { time: '15:25', type: 'info', message: 'D-04 센서 데이터 수집 시작' },
  { time: '15:20', type: 'danger', message: '유류오염 확산 속도 증가 감지' },
  { time: '15:15', type: 'info', message: '3D 재구성 시작 (불명선박-B)' },
]

// ── 유틸 ────────────────────────────────────────────────
function hexToRgba(hex: string): [number, number, number, number] {
  const r = parseInt(hex.slice(1, 3), 16)
  const g = parseInt(hex.slice(3, 5), 16)
  const b = parseInt(hex.slice(5, 7), 16)
  return [r, g, b, 255]
}

// ── 컴포넌트 ────────────────────────────────────────────
export function RealtimeDrone() {
  const [reconProgress, setReconProgress] = useState(0)
  const [reconDone, setReconDone] = useState(false)
  const [selectedDrone, setSelectedDrone] = useState<string | null>(null)
  const [animFrame, setAnimFrame] = useState(0)

  // 3D 재구성 진행률
  useEffect(() => {
    if (reconDone) return
    const timer = setInterval(() => {
      setReconProgress(prev => {
        if (prev >= 100) {
          clearInterval(timer)
          setReconDone(true)
          return 100
        }
        return prev + 2
      })
    }, 300)
    return () => clearInterval(timer)
  }, [reconDone])

  // 애니메이션 루프 (~20fps)
  useEffect(() => {
    let frame = 0
    let raf: number
    const tick = () => {
      frame++
      if (frame % 3 === 0) setAnimFrame(f => f + 1)
      raf = requestAnimationFrame(tick)
    }
    raf = requestAnimationFrame(tick)
    return () => cancelAnimationFrame(raf)
  }, [])

  const activeDrones = useMemo(() => drones.filter(d => d.status !== 'charging'), [])

  // ── deck.gl 레이어 ──────────────────────────────────
  const deckLayers = useMemo(() => {
    const t = animFrame * 0.05

    // 탐색 구역 (반투명 원 + 테두리)
    const zoneFillLayer = new ScatterplotLayer<ZoneInfo>({
      id: 'search-zones-fill',
      data: searchZones,
      getPosition: d => [d.lon, d.lat],
      getRadius: d => d.radius + Math.sin(t + searchZones.indexOf(d)) * 100,
      getFillColor: d => [...d.color, 15],
      getLineColor: d => [...d.color, 80],
      getLineWidth: 2,
      filled: true,
      stroked: true,
      radiusUnits: 'meters',
      radiusMinPixels: 30,
      lineWidthMinPixels: 1.5,
    })

    // 구역 라벨
    const zoneLabels = new TextLayer<ZoneInfo>({
      id: 'zone-labels',
      data: searchZones,
      getPosition: d => [d.lon, d.lat + 0.025],
      getText: d => `${d.id}구역`,
      getColor: d => [...d.color, 180],
      getSize: 12,
      fontFamily: 'NanumSquare, Malgun Gothic, 맑은 고딕, sans-serif',
      fontWeight: 'bold',
      characterSet: 'auto',
      outlineWidth: 2,
      outlineColor: [15, 21, 36, 180],
      getTextAnchor: 'middle',
      getAlignmentBaseline: 'center',
      billboard: false,
    })

    // 유류 확산 (동심원 3개)
    const oilRings = [0, 1, 2].map(ring =>
      new ScatterplotLayer({
        id: `oil-spill-${ring}`,
        data: [oilSpill],
        getPosition: () => [oilSpill.lon, oilSpill.lat],
        getRadius: 800 + ring * 500 + Math.sin(t * 0.5 + ring) * 80,
        getFillColor: [249, 115, 22, Math.max(4, 20 - ring * 6)],
        getLineColor: [249, 115, 22, ring === 0 ? 120 : 40],
        getLineWidth: ring === 0 ? 2 : 1,
        filled: true,
        stroked: true,
        radiusUnits: 'meters',
        radiusMinPixels: 15,
        lineWidthMinPixels: ring === 0 ? 1.5 : 0.8,
      }),
    )

    // 유류 확산 라벨
    const oilLabel = new TextLayer({
      id: 'oil-label',
      data: [oilSpill],
      getPosition: () => [oilSpill.lon, oilSpill.lat - 0.015],
      getText: () => '유류확산',
      getColor: [249, 115, 22, 200],
      getSize: 11,
      fontFamily: 'NanumSquare, Malgun Gothic, 맑은 고딕, sans-serif',
      fontWeight: 'bold',
      characterSet: 'auto',
      outlineWidth: 2,
      outlineColor: [15, 21, 36, 180],
      getTextAnchor: 'middle',
      getAlignmentBaseline: 'center',
      billboard: false,
    })

    // HNS 의심
    const hnsLayer = new ScatterplotLayer({
      id: 'hns-point',
      data: [hnsPoint],
      getPosition: () => [hnsPoint.lon, hnsPoint.lat],
      getRadius: 400 + Math.sin(t * 1.2) * 80,
      getFillColor: [234, 179, 8, 50],
      getLineColor: [234, 179, 8, 100],
      getLineWidth: 1.5,
      filled: true,
      stroked: true,
      radiusUnits: 'meters',
      radiusMinPixels: 6,
      lineWidthMinPixels: 1,
    })
    const hnsCore = new ScatterplotLayer({
      id: 'hns-core',
      data: [hnsPoint],
      getPosition: () => [hnsPoint.lon, hnsPoint.lat],
      getRadius: 150,
      getFillColor: [234, 179, 8, 200],
      filled: true,
      radiusUnits: 'meters',
      radiusMinPixels: 4,
    })
    const hnsLabel = new TextLayer({
      id: 'hns-label',
      data: [hnsPoint],
      getPosition: () => [hnsPoint.lon, hnsPoint.lat - 0.008],
      getText: () => 'HNS 의심',
      getColor: [234, 179, 8, 180],
      getSize: 10,
      fontFamily: 'NanumSquare, Malgun Gothic, 맑은 고딕, sans-serif',
      fontWeight: 'bold',
      characterSet: 'auto',
      outlineWidth: 2,
      outlineColor: [15, 21, 36, 180],
      getTextAnchor: 'middle',
      getAlignmentBaseline: 'center',
      billboard: false,
    })

    // 선박 — AIS OFF는 red 경고 원
    const vesselAlertLayer = new ScatterplotLayer<VesselInfo>({
      id: 'vessel-alert',
      data: vessels.filter(v => v.aisOff),
      getPosition: d => [d.lon, d.lat],
      getRadius: 600 + Math.sin(t * 1.5) * 150,
      getFillColor: [239, 68, 68, 20],
      getLineColor: [239, 68, 68, 60],
      getLineWidth: 1,
      filled: true,
      stroked: true,
      radiusUnits: 'meters',
      radiusMinPixels: 10,
      lineWidthMinPixels: 0.8,
    })
    const vesselLayer = new ScatterplotLayer<VesselInfo>({
      id: 'vessels',
      data: vessels,
      getPosition: d => [d.lon, d.lat],
      getRadius: 200,
      getFillColor: d => d.aisOff ? [239, 68, 68, 255] : [96, 165, 250, 255],
      getLineColor: d => d.aisOff ? [239, 68, 68, 120] : [96, 165, 250, 80],
      getLineWidth: 1.5,
      filled: true,
      stroked: true,
      radiusUnits: 'meters',
      radiusMinPixels: 5,
      lineWidthMinPixels: 1,
    })
    const vesselLabels = new TextLayer<VesselInfo>({
      id: 'vessel-labels',
      data: vessels,
      getPosition: d => [d.lon, d.lat + 0.005],
      getText: d => d.name,
      getColor: [255, 255, 255, 190],
      getSize: 11,
      fontFamily: 'NanumSquare, Malgun Gothic, 맑은 고딕, sans-serif',
      fontWeight: 'bold',
      characterSet: 'auto',
      outlineWidth: 2,
      outlineColor: [15, 21, 36, 180],
      getTextAnchor: 'middle',
      getAlignmentBaseline: 'center',
      billboard: false,
    })

    // 드론 간 메시 링크
    const droneLinks: { path: [number, number][] }[] = []
    for (let i = 0; i < activeDrones.length; i++) {
      for (let j = i + 1; j < activeDrones.length; j++) {
        const a = activeDrones[i]
        const b = activeDrones[j]
        droneLinks.push({
          path: [
            [a.lon + Math.sin(t + i * 2) * 0.002, a.lat + Math.cos(t * 0.8 + i) * 0.001],
            [b.lon + Math.sin(t + j * 2) * 0.002, b.lat + Math.cos(t * 0.8 + j) * 0.001],
          ],
        })
      }
    }
    const linkLayer = new PathLayer({
      id: 'drone-links',
      data: droneLinks,
      getPath: d => d.path,
      getColor: [77, 208, 225, 35],
      getWidth: 1,
      getDashArray: [6, 8],
      dashJustified: true,
      widthMinPixels: 0.7,
    })

    // 드론 글로우 (뒤쪽 큰 원)
    const droneGlowLayer = new ScatterplotLayer<DroneInfo>({
      id: 'drone-glow',
      data: activeDrones,
      getPosition: d => {
        const i = activeDrones.indexOf(d)
        return [
          d.lon + Math.sin(t + i * 2) * 0.002,
          d.lat + Math.cos(t * 0.8 + i) * 0.001,
        ]
      },
      getRadius: d => selectedDrone === d.id ? 500 : 350,
      getFillColor: d => {
        const [r, g, b] = hexToRgba(d.color)
        return [r, g, b, selectedDrone === d.id ? 40 : 20]
      },
      filled: true,
      radiusUnits: 'meters',
      radiusMinPixels: selectedDrone ? 12 : 8,
      updateTriggers: {
        getPosition: [animFrame],
        getFillColor: [selectedDrone],
        getRadius: [selectedDrone],
      },
    })

    // 드론 본체
    const droneLayer = new ScatterplotLayer<DroneInfo>({
      id: 'drones',
      data: activeDrones,
      getPosition: d => {
        const i = activeDrones.indexOf(d)
        return [
          d.lon + Math.sin(t + i * 2) * 0.002,
          d.lat + Math.cos(t * 0.8 + i) * 0.001,
        ]
      },
      getRadius: d => selectedDrone === d.id ? 200 : 150,
      getFillColor: d => hexToRgba(d.color),
      getLineColor: [255, 255, 255, 200],
      getLineWidth: d => selectedDrone === d.id ? 2 : 1,
      filled: true,
      stroked: true,
      radiusUnits: 'meters',
      radiusMinPixels: selectedDrone ? 6 : 4,
      lineWidthMinPixels: 1,
      pickable: true,
      onClick: (info: PickingInfo<DroneInfo>) => {
        if (info.object) setSelectedDrone(info.object.id)
      },
      updateTriggers: {
        getPosition: [animFrame],
        getRadius: [selectedDrone],
        getLineWidth: [selectedDrone],
      },
    })

    // 드론 라벨
    const droneLabels = new TextLayer<DroneInfo>({
      id: 'drone-labels',
      data: activeDrones,
      getPosition: d => {
        const i = activeDrones.indexOf(d)
        return [
          d.lon + Math.sin(t + i * 2) * 0.002,
          d.lat + Math.cos(t * 0.8 + i) * 0.001 + 0.006,
        ]
      },
      getText: d => d.id,
      getColor: d => {
        const [r, g, b] = hexToRgba(d.color)
        return selectedDrone === d.id ? [255, 255, 255, 255] : [r, g, b, 230]
      },
      getSize: d => selectedDrone === d.id ? 13 : 10,
      fontFamily: 'Outfit, monospace',
      fontWeight: 'bold',
      characterSet: 'auto',
      outlineWidth: 2,
      outlineColor: [15, 21, 36, 200],
      getTextAnchor: 'middle',
      getAlignmentBaseline: 'center',
      billboard: false,
      updateTriggers: {
        getPosition: [animFrame],
        getColor: [selectedDrone],
        getSize: [selectedDrone],
      },
    })

    return [
      zoneFillLayer,
      zoneLabels,
      ...oilRings,
      oilLabel,
      hnsLayer,
      hnsCore,
      hnsLabel,
      vesselAlertLayer,
      vesselLayer,
      vesselLabels,
      linkLayer,
      droneGlowLayer,
      droneLayer,
      droneLabels,
    ]
  }, [animFrame, selectedDrone, activeDrones])

  // ── UI 유틸 ───────────────────────────────────────────
  const statusLabel = (s: string) => {
    if (s === 'active') return { text: '비행중', cls: 'text-status-green' }
    if (s === 'returning') return { text: '복귀중', cls: 'text-status-orange' }
    if (s === 'charging') return { text: '충전중', cls: 'text-text-3' }
    return { text: '대기', cls: 'text-text-3' }
  }

  const alertColor = (t: string) =>
    t === 'danger' ? 'border-l-status-red bg-[rgba(239,68,68,0.05)]'
    : t === 'warning' ? 'border-l-status-orange bg-[rgba(249,115,22,0.05)]'
    : 'border-l-primary-blue bg-[rgba(59,130,246,0.05)]'

  return (
    <div className="flex h-full overflow-hidden" style={{ margin: '-20px -24px', height: 'calc(100% + 40px)' }}>
      {/* 지도 영역 */}
      <div className="flex-1 relative overflow-hidden">
        <Map
          initialViewState={{
            longitude: 128.75,
            latitude: 34.64,
            zoom: 10,
          }}
          mapStyle={BASE_STYLE}
          className="w-full h-full"
          attributionControl={false}
        >
          <DeckGLOverlay layers={deckLayers} />
        </Map>

        {/* 오버레이 통계 */}
        <div className="absolute top-2.5 left-2.5 flex gap-1.5 z-[2] pointer-events-none">
          {[
            { label: '탐지 객체', value: '847', unit: '건', color: 'text-primary-blue' },
            { label: '식별 선박', value: '312', unit: '척', color: 'text-primary-cyan' },
            { label: 'AIS OFF', value: '14', unit: '척', color: 'text-status-red' },
            { label: '오염 탐지', value: '3', unit: '건', color: 'text-status-orange' },
          ].map((s, i) => (
            <div key={i} className="bg-[rgba(15,21,36,0.9)] backdrop-blur-sm rounded-sm px-2.5 py-1.5 border border-border">
              <div className="text-[7px] text-text-3">{s.label}</div>
              <div>
                <span className={`font-mono font-bold text-base ${s.color}`}>{s.value}</span>
                <span className="text-[7px] text-text-3 ml-0.5">{s.unit}</span>
              </div>
            </div>
          ))}
        </div>

        {/* 3D 재구성 진행률 */}
        <div className="absolute bottom-2.5 right-2.5 bg-[rgba(15,21,36,0.9)] rounded-sm px-3 py-2 border z-[3] min-w-[175px] cursor-pointer transition-colors hover:border-primary-cyan/40" style={{ borderColor: 'rgba(6,182,212,0.18)' }}>
          <div className="flex items-center justify-between mb-1">
            <span className="text-[9px] font-bold text-primary-cyan">🧊 3D 재구성</span>
            <span className="font-mono font-bold text-[13px] text-primary-cyan">{reconProgress}%</span>
          </div>
          <div className="w-full h-[3px] bg-white/[0.06] rounded-sm mb-1">
            <div className="h-full rounded-sm transition-all duration-500" style={{ width: `${reconProgress}%`, background: 'linear-gradient(90deg, var(--cyan), var(--blue))' }} />
          </div>
          {!reconDone ? (
            <div className="text-[7px] text-text-3">D-01~D-03 다각도 영상 융합중...</div>
          ) : (
            <div className="text-[8px] font-bold text-status-green mt-0.5 animate-pulse-dot">✅ 완료 — 클릭하여 정밀분석</div>
          )}
        </div>

        {/* 실시간 영상 패널 */}
        {selectedDrone && (() => {
          const drone = drones.find(d => d.id === selectedDrone)
          if (!drone) return null
          return (
            <div className="absolute bottom-0 left-0 right-0 bg-[rgba(15,21,36,0.95)] z-[5] border-t" style={{ borderColor: 'rgba(59,130,246,0.2)', height: 190 }}>
              <div className="flex items-center justify-between px-3 py-1.5 border-b border-border">
                <div className="text-[10px] font-bold flex items-center gap-1.5" style={{ color: drone.color }}>
                  <div className="w-1.5 h-1.5 rounded-full animate-pulse-dot" style={{ background: drone.color }} />
                  {drone.id} 실시간 영상
                </div>
                <button onClick={() => setSelectedDrone(null)} className="w-5 h-5 rounded bg-white/5 border border-border text-text-3 text-[11px] flex items-center justify-center cursor-pointer hover:text-text-1">✕</button>
              </div>
              <div className="grid h-[calc(100%-30px)]" style={{ gridTemplateColumns: '1fr 180px' }}>
                <div className="relative overflow-hidden" style={{ background: 'radial-gradient(ellipse at center, #0c1a2e, #060c18)' }}>
                  <div className="absolute inset-0 flex items-center justify-center">
                    <div className="text-text-3/20 text-2xl font-mono">LIVE FEED</div>
                  </div>
                  <div className="absolute top-1.5 left-2 z-[2]">
                    <span className="text-[11px] font-bold" style={{ color: drone.color }}>{drone.id}</span>
                    <span className="text-[7px] px-1 py-px rounded bg-white/[0.08] ml-1">{drone.sensor}</span>
                    <div className="text-[7px] text-text-3 font-mono mt-0.5">{drone.lat.toFixed(2)}°N, {drone.lon.toFixed(2)}°E</div>
                  </div>
                  <div className="absolute top-1.5 right-2 z-[2] flex items-center gap-1 text-[8px] font-bold text-status-red">
                    <div className="w-1.5 h-1.5 rounded-full bg-status-red" />REC
                  </div>
                  <div className="absolute bottom-1 left-2 z-[2] text-[7px] text-text-3">
                    ALT {drone.altitude}m · SPD {drone.speed}m/s · HDG 045°
                  </div>
                </div>
                <div className="p-2 overflow-auto text-[9px] border-l border-border">
                  <div className="font-bold text-text-2 mb-1.5 font-korean">비행 정보</div>
                  {[
                    ['드론 ID', drone.id],
                    ['기체', drone.name],
                    ['배터리', `${drone.battery}%`],
                    ['고도', `${drone.altitude}m`],
                    ['속도', `${drone.speed}m/s`],
                    ['센서', drone.sensor],
                    ['상태', statusLabel(drone.status).text],
                  ].map(([k, v], i) => (
                    <div key={i} className="flex justify-between py-0.5">
                      <span className="text-text-3 font-korean">{k}</span>
                      <span className="font-mono font-semibold text-text-1">{v}</span>
                    </div>
                  ))}
                </div>
              </div>
            </div>
          )
        })()}
      </div>

      {/* 우측 사이드바 */}
      <div className="w-[260px] bg-[rgba(15,21,36,0.88)] border-l border-border flex flex-col overflow-auto">
        {/* 군집 드론 현황 */}
        <div className="p-2.5 px-3 border-b border-border">
          <div className="text-[10px] font-bold text-text-3 mb-1.5 uppercase tracking-wider">군집 드론 현황 · {activeDrones.length}/{drones.length} 운용</div>
          <div className="flex flex-col gap-1">
            {drones.map(d => {
              const st = statusLabel(d.status)
              return (
                <div
                  key={d.id}
                  onClick={() => d.status !== 'charging' && setSelectedDrone(d.id)}
                  className={`flex items-center gap-2 px-2 py-1.5 rounded-sm cursor-pointer transition-colors ${
                    selectedDrone === d.id ? 'bg-[rgba(6,182,212,0.08)] border border-primary-cyan/20' : 'hover:bg-white/[0.02] border border-transparent'
                  }`}
                >
                  <div className="w-2 h-2 rounded-full" style={{ background: d.color }} />
                  <div className="flex-1 min-w-0">
                    <div className="text-[9px] font-bold" style={{ color: d.color }}>{d.id}</div>
                    <div className="text-[7px] text-text-3 truncate">{d.name}</div>
                  </div>
                  <div className="text-right">
                    <div className={`text-[8px] font-semibold ${st.cls}`}>{st.text}</div>
                    <div className="text-[7px] font-mono text-text-3">{d.battery}%</div>
                  </div>
                </div>
              )
            })}
          </div>
        </div>

        {/* 다각화 분석 */}
        <div className="p-2.5 px-3 border-b border-border">
          <div className="text-[10px] font-bold text-text-3 mb-1.5 uppercase tracking-wider">다각화 분석</div>
          <div className="grid grid-cols-2 gap-1">
            {[
              { icon: '🎯', label: '다시점 융합', value: '28건', sub: '360° 식별' },
              { icon: '🧊', label: '3D 재구성', value: '12건', sub: '선박+오염원' },
              { icon: '📡', label: '다센서 융합', value: '45건', sub: '광학+IR+SAR' },
              { icon: '🛢️', label: '오염원 3D', value: '3건', sub: '유류+HNS' },
            ].map((a, i) => (
              <div key={i} className="bg-white/[0.02] rounded-sm px-1.5 py-1.5 border border-white/[0.03]">
                <div className="text-[10px] mb-px">{a.icon}</div>
                <div className="text-[7px] text-text-3">{a.label}</div>
                <div className="text-xs font-bold font-mono text-primary-cyan my-px">{a.value}</div>
                <div className="text-[6px] text-text-3">{a.sub}</div>
              </div>
            ))}
          </div>
        </div>

        {/* 실시간 경보 */}
        <div className="p-2.5 px-3 flex-1 overflow-auto">
          <div className="text-[10px] font-bold text-text-3 mb-1.5 uppercase tracking-wider">실시간 경보</div>
          <div className="flex flex-col gap-1">
            {alerts.map((a, i) => (
              <div key={i} className={`px-2 py-1.5 border-l-2 rounded-sm text-[9px] font-korean ${alertColor(a.type)}`}>
                <span className="font-mono text-text-3 mr-1.5">{a.time}</span>
                <span className="text-text-2">{a.message}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  )
}
