import { useState, useRef, useEffect, useCallback } from 'react'
import { Map, Source, Layer } from '@vis.gl/react-maplibre'
import type { StyleSpecification } from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css'
import { Marker } from '@vis.gl/react-maplibre'
import { fetchSatellitePasses } from '../services/aerialApi'

const VWORLD_API_KEY = import.meta.env.VITE_VWORLD_API_KEY || ''
import type { SatellitePass } from '../services/aerialApi'

interface SatRequest {
  id: string
  zone: string
  zoneCoord: string
  zoneArea: string
  satellite: string
  requestDate: string
  expectedReceive: string
  resolution: string
  status: '촬영중' | '대기' | '완료' | '취소'
  provider?: string
  purpose?: string
  requester?: string
  /** ISO 날짜 (필터용) */
  dateKey?: string
}

const satRequests: SatRequest[] = [
  { id: 'SAT-004', zone: '제주 서귀포 해상 (유출 해역 중심)', zoneCoord: '33.24°N 126.50°E', zoneArea: '15km²', satellite: 'KOMPSAT-3A', requestDate: '03-17 08:14', expectedReceive: '03-17 14:30', resolution: '0.5m', status: '촬영중', provider: 'KARI', purpose: '유출유 확산 모니터링', requester: '방제과 김해양', dateKey: '2026-03-17' },
  { id: 'SAT-005', zone: '가파도 북쪽 해안선', zoneCoord: '33.17°N 126.27°E', zoneArea: '8km²', satellite: 'KOMPSAT-3', requestDate: '03-17 09:02', expectedReceive: '03-18 09:00', resolution: '1.0m', status: '대기', provider: 'KARI', purpose: '해안선 오염 확인', requester: '방제과 이민수', dateKey: '2026-03-17' },
  { id: 'SAT-006', zone: '마라도 주변 해역', zoneCoord: '33.11°N 126.27°E', zoneArea: '12km²', satellite: 'Sentinel-2', requestDate: '03-16 09:30', expectedReceive: '03-16 23:00', resolution: '10m', status: '완료', provider: 'ESA Copernicus', purpose: '수질 분석용 다분광 촬영', requester: '환경분석팀 박수진', dateKey: '2026-03-16' },
  { id: 'SAT-007', zone: '대정읍 해안 오염 확산 구역', zoneCoord: '33.21°N 126.10°E', zoneArea: '20km²', satellite: 'KOMPSAT-3A', requestDate: '03-16 10:05', expectedReceive: '03-17 08:00', resolution: '0.5m', status: '완료', provider: 'KARI', purpose: '확산 예측 모델 검증', requester: '방제과 김해양', dateKey: '2026-03-16' },
  { id: 'SAT-003', zone: '제주 남방 100해리 해상', zoneCoord: '33.00°N 126.50°E', zoneArea: '25km²', satellite: 'Sentinel-1', requestDate: '03-15 14:00', expectedReceive: '03-15 23:00', resolution: '20m', status: '완료', provider: 'ESA Copernicus', purpose: 'SAR 유막 탐지', requester: '환경분석팀 박수진', dateKey: '2026-03-15' },
  { id: 'SAT-002', zone: '여수 오동도 인근 해역', zoneCoord: '34.73°N 127.68°E', zoneArea: '18km²', satellite: 'KOMPSAT-3A', requestDate: '03-14 11:30', expectedReceive: '03-14 17:45', resolution: '0.5m', status: '완료', provider: 'KARI', purpose: '유출 초기 범위 확인', requester: '방제과 김해양', dateKey: '2026-03-14' },
  { id: 'SAT-001', zone: '통영 해역 남측', zoneCoord: '34.85°N 128.43°E', zoneArea: '30km²', satellite: 'Sentinel-1', requestDate: '03-13 09:00', expectedReceive: '03-13 21:00', resolution: '20m', status: '완료', provider: 'ESA Copernicus', purpose: '야간 SAR 유막 모니터링', requester: '환경분석팀 박수진', dateKey: '2026-03-13' },
]

const satellites = [
  { name: 'KOMPSAT-3A', desc: '해상도 0.5m · 광학 / IR · 촬영 가능', status: '가용', statusColor: 'var(--green)', borderColor: 'rgba(34,197,94,.2)', pulse: true },
  { name: 'KOMPSAT-3', desc: '해상도 1.0m · 광학 · 임무 중', status: '임무중', statusColor: 'var(--yellow)', borderColor: 'rgba(234,179,8,.2)', pulse: true },
  { name: 'Sentinel-1 (ESA)', desc: '해상도 20m · SAR · 야간/우천 가능', status: '가용', statusColor: 'var(--green)', borderColor: 'var(--bd)', pulse: false },
  { name: 'Sentinel-2 (ESA)', desc: '해상도 10m · 다분광 · 수질 분석 적합', status: '가용', statusColor: 'var(--green)', borderColor: 'var(--bd)', pulse: false },
]

const passSchedules = [
  { time: '14:10 – 14:24', desc: 'KOMPSAT-3A 패스 (제주 남방)', today: true },
  { time: '16:55 – 17:08', desc: 'Sentinel-1 패스 (제주 전역)', today: true },
  { time: '내일 09:12', desc: 'KOMPSAT-3 패스 (가파도~마라도)', today: false },
  { time: '내일 10:40', desc: 'Sentinel-2 패스 (제주 서측)', today: false },
]

// UP42 위성 카탈로그 데이터
const up42Satellites = [
  { id: 'mwl-hd15', name: 'Maxar WorldView Legion HD15', res: '0.3m', type: 'optical' as const, color: '#3b82f6', cloud: 15 },
  { id: 'pneo-hd15', name: 'Pléiades Neo HD15', res: '0.3m', type: 'optical' as const, color: '#06b6d4', cloud: 10 },
  { id: 'mwl', name: 'Maxar WorldView Legion', res: '0.5m', type: 'optical' as const, color: '#3b82f6', cloud: 20 },
  { id: 'mwv3', name: 'Maxar WorldView-3', res: '0.5m', type: 'optical' as const, color: '#3b82f6', cloud: 20 },
  { id: 'pneo', name: 'Pléiades Neo', res: '0.5m', type: 'optical' as const, color: '#06b6d4', cloud: 15 },
  { id: 'bj3n', name: 'Beijing-3N', res: '0.5m', type: 'optical' as const, color: '#f97316', cloud: 20, delay: true },
  { id: 'skysat', name: 'SkySat', res: '0.7m', type: 'optical' as const, color: '#22c55e', cloud: 15 },
  { id: 'kmp3a', name: 'KOMPSAT-3A', res: '0.5m', type: 'optical' as const, color: '#a855f7', cloud: 10 },
  { id: 'kmp3', name: 'KOMPSAT-3', res: '1.0m', type: 'optical' as const, color: '#a855f7', cloud: 15 },
  { id: 'spot7', name: 'SPOT 7', res: '1.5m', type: 'optical' as const, color: '#eab308', cloud: 20 },
  { id: 's2', name: 'Sentinel-2', res: '10m', type: 'optical' as const, color: '#ec4899', cloud: 20 },
  { id: 's1', name: 'Sentinel-1 SAR', res: '20m', type: 'sar' as const, color: '#f59e0b', cloud: 0 },
  { id: 'alos2', name: 'ALOS-2 PALSAR-2', res: '3m', type: 'sar' as const, color: '#f59e0b', cloud: 0 },
  { id: 'rcm', name: 'RCM (Radarsat)', res: '3m', type: 'sar' as const, color: '#f59e0b', cloud: 0 },
  { id: 'srtm', name: 'SRTM DEM', res: '30m', type: 'elevation' as const, color: '#64748b', cloud: 0 },
  { id: 'cop-dem', name: 'Copernicus DEM', res: '10m', type: 'elevation' as const, color: '#64748b', cloud: 0 },
]

// up42Passes — 실시간 패스로 대체됨 (satPasses from API)

const SAT_MAP_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,
    },
  },
  layers: [{ id: 'carto-dark-layer', type: 'raster', source: 'carto-dark', minzoom: 0, maxzoom: 22 }],
}

/** 좌표 문자열 파싱 ("33.24°N 126.50°E" → {lat, lon}) */
function parseCoord(coordStr: string): { lat: number; lon: number } | null {
  const m = coordStr.match(/([\d.]+)°N\s+([\d.]+)°E/)
  if (!m) return null
  return { lat: parseFloat(m[1]), lon: parseFloat(m[2]) }
}

type SatModalPhase = 'none' | 'provider' | 'blacksky' | 'up42'

export function SatelliteRequest() {
  const [requests, setRequests] = useState(satRequests)
  const [mainTab, setMainTab] = useState<'list' | 'map'>('list')
  const [statusFilter, setStatusFilter] = useState('전체')
  const [modalPhase, setModalPhase] = useState<SatModalPhase>('none')
  const [selectedRequest, setSelectedRequest] = useState<SatRequest | null>(null)
  const [currentPage, setCurrentPage] = useState(1)
  const PAGE_SIZE = 5
  // UP42 sub-tab
  const [up42SubTab, setUp42SubTab] = useState<'optical' | 'sar' | 'elevation'>('optical')
  const [up42SelSat, setUp42SelSat] = useState<string | null>(null)
  const [up42SelPass, setUp42SelPass] = useState<string | null>(null)
  const [satPasses, setSatPasses] = useState<SatellitePass[]>([])
  const [satPassesLoading, setSatPassesLoading] = useState(false)
  // 히스토리 지도 — 캘린더 + 선택 항목
  const [mapSelectedDate, setMapSelectedDate] = useState(() => {
    const d = new Date(); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
  })
  const [mapSelectedItem, setMapSelectedItem] = useState<SatRequest | null>(null)
  const satImgOpacity = 90
  const satImgBrightness = 100
  const satShowOverlay = true

  const modalRef = useRef<HTMLDivElement>(null)

  const loadSatPasses = useCallback(async () => {
    setSatPassesLoading(true)
    try {
      const passes = await fetchSatellitePasses()
      setSatPasses(passes)
    } catch {
      setSatPasses([])
    } finally {
      setSatPassesLoading(false)
    }
  }, [])

  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (modalRef.current && !modalRef.current.contains(e.target as Node)) {
        setModalPhase('none')
      }
    }
    if (modalPhase !== 'none') document.addEventListener('mousedown', handler)
    return () => document.removeEventListener('mousedown', handler)
  }, [modalPhase])

  // UP42 모달 열릴 때 위성 패스 로드
  useEffect(() => {
    if (modalPhase === 'up42') loadSatPasses()
  }, [modalPhase, loadSatPasses])

  const filtered = requests.filter(r => {
    if (statusFilter === '전체') return true
    if (statusFilter === '대기') return r.status === '대기'
    if (statusFilter === '진행') return r.status === '촬영중'
    if (statusFilter === '완료') return r.status === '완료'
    if (statusFilter === '취소') return r.status === '취소'
    return true
  })
  const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE))
  const pagedItems = filtered.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE)

  const statusBadge = (s: SatRequest['status']) => {
    if (s === '촬영중') return (
      <span className="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-[10px] font-semibold font-korean" style={{ background: 'rgba(234,179,8,.15)', border: '1px solid rgba(234,179,8,.3)', color: 'var(--yellow)' }}>
        <span className="w-[5px] h-[5px] rounded-full inline-block animate-pulse" style={{ background: 'var(--yellow)' }} />촬영중
      </span>
    )
    if (s === '대기') return (
      <span className="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-[10px] font-semibold font-korean" style={{ background: 'rgba(59,130,246,.15)', border: '1px solid rgba(59,130,246,.3)', color: 'var(--blue)' }}>⏳ 대기</span>
    )
    if (s === '취소') return (
      <span className="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-[10px] font-semibold font-korean" style={{ background: 'rgba(239,68,68,.1)', border: '1px solid rgba(239,68,68,.2)', color: 'var(--red)' }}>✕ 취소</span>
    )
    return (
      <span className="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-[10px] font-semibold font-korean" style={{ background: 'rgba(34,197,94,.1)', border: '1px solid rgba(34,197,94,.2)', color: 'var(--green)' }}>✅ 완료</span>
    )
  }

  const stats = [
    { value: '3', label: '요청 대기', color: 'var(--blue)' },
    { value: '1', label: '촬영 진행 중', color: 'var(--yellow)' },
    { value: '7', label: '수신 완료', color: 'var(--green)' },
    { value: '0.5m', label: '최고 해상도', color: 'var(--cyan)' },
  ]

  const filters = ['전체', '대기', '진행', '완료', '취소']

  const up42Filtered = up42Satellites.filter(s => s.type === up42SubTab)

  // ── 섹션 헤더 헬퍼 (BlackSky 폼) ──
  const sectionHeader = (num: number, label: string) => (
    <div className="text-[11px] font-bold font-korean mb-2.5 flex items-center gap-1.5 text-[#818cf8]">
      <div className="w-[18px] h-[18px] rounded-[5px] flex items-center justify-center text-[9px] font-bold text-[#818cf8]" style={{ background: 'rgba(99,102,241,.12)' }}>{num}</div>
      {label}
    </div>
  )

  const bsInput = "w-full px-3 py-2 rounded-md text-[11px] font-korean outline-none box-border"
  const bsInputStyle = { border: '1px solid #21262d', background: '#161b22', color: '#e2e8f0' }

  return (
    <div className="overflow-y-auto px-6 pt-1 pb-2" style={{ height: mainTab === 'map' ? '100%' : undefined }}>
      {/* 헤더 + 탭 + 새요청 한 줄 (높이 통일) */}
      <div className="flex items-center gap-3 mb-2 h-9">
        <div className="flex items-center gap-2 shrink-0">
          <div className="w-7 h-7 rounded-md flex items-center justify-center text-sm" style={{ background: 'linear-gradient(135deg,rgba(59,130,246,.2),rgba(168,85,247,.2))', border: '1px solid rgba(59,130,246,.3)' }}>🛰</div>
          <div className="text-[12px] font-bold font-korean text-text-1">위성 촬영 요청</div>
        </div>
        <div className="flex gap-1 h-7">
          <button
            onClick={() => setMainTab('list')}
            className="px-2.5 h-full rounded text-[10px] font-bold font-korean cursor-pointer border transition-colors"
            style={mainTab === 'list'
              ? { background: 'rgba(59,130,246,.12)', borderColor: 'rgba(59,130,246,.3)', color: 'var(--blue)' }
              : { background: 'var(--bg3)', borderColor: 'var(--bd)', color: 'var(--t3)' }
            }
          >📋 요청 목록</button>
          <button
            onClick={() => setMainTab('map')}
            className="px-2.5 h-full rounded text-[10px] font-bold font-korean cursor-pointer border transition-colors"
            style={mainTab === 'map'
              ? { background: 'rgba(59,130,246,.12)', borderColor: 'rgba(59,130,246,.3)', color: 'var(--blue)' }
              : { background: 'var(--bg3)', borderColor: 'var(--bd)', color: 'var(--t3)' }
            }
          >🗺 히스토리 지도</button>
        </div>
        <button onClick={() => setModalPhase('provider')} className="ml-auto px-3 h-7 text-white border-none rounded-sm text-[10px] font-semibold cursor-pointer font-korean flex items-center gap-1 shrink-0" style={{ background: 'linear-gradient(135deg,var(--blue),var(--purple))' }}>🛰 새 요청</button>
      </div>

      {mainTab === 'list' && (<>
      {/* 요약 통계 */}
      <div className="grid grid-cols-4 gap-3 mb-5">
        {stats.map((s, i) => (
          <div key={i} className="bg-bg-2 border border-border rounded-md p-3.5 text-center">
            <div className="text-[22px] font-bold font-mono" style={{ color: s.color }}>{s.value}</div>
            <div className="text-[10px] text-text-3 mt-1 font-korean">{s.label}</div>
          </div>
        ))}
      </div>

      {/* 요청 목록 */}
      <div className="bg-bg-2 border border-border rounded-md overflow-hidden mb-5">
        <div className="flex items-center justify-between px-4 py-3.5 border-b border-border">
          <div className="text-[13px] font-bold font-korean text-text-1">📋 위성 요청 목록</div>
          <div className="flex gap-1.5">
            {filters.map(f => (
              <button
                key={f}
                onClick={() => setStatusFilter(f)}
                className="px-2.5 py-1 rounded text-[10px] font-semibold cursor-pointer font-korean border"
                style={statusFilter === f
                  ? { background: 'rgba(59,130,246,.15)', color: 'var(--blue)', borderColor: 'rgba(59,130,246,.3)' }
                  : { background: 'var(--bg3)', color: 'var(--t2)', borderColor: 'var(--bd)' }
                }
              >{f}</button>
            ))}
          </div>
        </div>

        {/* 헤더 행 */}
        <div className="grid gap-0 px-4 py-2 bg-bg-3 border-b border-border" style={{ gridTemplateColumns: '60px 1fr 100px 100px 120px 80px 90px' }}>
          {['번호', '촬영 구역', '위성', '요청일시', '예상수신', '해상도', '상태'].map(h => (
            <div key={h} className="text-[9px] font-bold text-text-3 font-korean uppercase tracking-wider">{h}</div>
          ))}
        </div>

        {/* 데이터 행 (페이징) */}
        {pagedItems.map(r => (
          <div key={r.id}>
            <div
              onClick={() => setSelectedRequest(selectedRequest?.id === r.id ? null : r)}
              className="grid gap-0 px-4 py-3 border-b items-center cursor-pointer hover:bg-bg-hover/30 transition-colors"
              style={{
                gridTemplateColumns: '60px 1fr 100px 100px 120px 80px 90px',
                borderColor: 'rgba(255,255,255,.04)',
                background: selectedRequest?.id === r.id ? 'rgba(99,102,241,.06)' : r.status === '촬영중' ? 'rgba(234,179,8,.03)' : 'transparent',
                opacity: (r.status === '완료' || r.status === '취소') ? 0.6 : 1,
              }}
            >
              <div className="text-[11px] font-mono text-text-2">{r.id}</div>
              <div>
                <div className="text-xs font-semibold text-text-1 font-korean">{r.zone}</div>
                <div className="text-[10px] text-text-3 font-mono mt-0.5">{r.zoneCoord}  ·  {r.zoneArea}</div>
              </div>
              <div className="text-[11px] font-semibold text-text-1 font-korean">{r.satellite}</div>
              <div className="text-[10px] text-text-2 font-mono">{r.requestDate}</div>
              <div className="text-[10px] font-semibold font-mono" style={{ color: r.status === '촬영중' ? 'var(--yellow)' : 'var(--t2)' }}>{r.expectedReceive}</div>
              <div className="text-[11px] font-bold font-mono" style={{ color: r.status === '완료' ? 'var(--t3)' : 'var(--cyan)' }}>{r.resolution}</div>
              <div>{statusBadge(r.status)}</div>
            </div>
            {/* 상세 정보 패널 */}
            {selectedRequest?.id === r.id && (
              <div className="px-4 py-3 border-b" style={{ borderColor: 'rgba(255,255,255,.04)', background: 'rgba(99,102,241,.03)' }}>
                <div className="grid grid-cols-4 gap-3 mb-2">
                  {[
                    ['제공자', r.provider || '-'],
                    ['요청 목적', r.purpose || '-'],
                    ['요청자', r.requester || '-'],
                    ['촬영 면적', r.zoneArea],
                  ].map(([k, v], i) => (
                    <div key={i} className="px-2.5 py-2 bg-bg-0 rounded">
                      <div className="text-[8px] font-bold text-text-3 font-korean mb-1 uppercase">{k}</div>
                      <div className="text-[10px] font-semibold text-text-1 font-korean">{v}</div>
                    </div>
                  ))}
                </div>
                <div className="flex gap-2">
                  <button className="px-3 py-1.5 text-[10px] font-semibold font-korean rounded border cursor-pointer hover:bg-bg-hover transition-colors" style={{ background: 'rgba(6,182,212,.08)', borderColor: 'rgba(6,182,212,.2)', color: 'var(--cyan)' }}>📍 지도에서 보기</button>
                  {r.status === '완료' && (
                    <button className="px-3 py-1.5 text-[10px] font-semibold font-korean rounded border cursor-pointer hover:bg-bg-hover transition-colors" style={{ background: 'rgba(34,197,94,.08)', borderColor: 'rgba(34,197,94,.2)', color: 'var(--green)' }}>📥 영상 다운로드</button>
                  )}
                  {(r.status === '대기' || r.status === '촬영중') && (
                    <button
                      onClick={(e) => {
                        e.stopPropagation()
                        if (confirm(`${r.id} (${r.zone}) 위성 촬영 요청을 취소하시겠습니까?`)) {
                          setRequests(prev => prev.map(req => req.id === r.id ? { ...req, status: '취소' as const } : req))
                          setSelectedRequest(null)
                        }
                      }}
                      className="px-3 py-1.5 text-[10px] font-semibold font-korean rounded border cursor-pointer hover:bg-bg-hover transition-colors"
                      style={{ background: 'rgba(239,68,68,.08)', borderColor: 'rgba(239,68,68,.2)', color: 'var(--red)' }}
                    >✕ 요청 취소</button>
                  )}
                </div>
              </div>
            )}
          </div>
        ))}

        {/* 페이징 */}
        <div className="flex items-center justify-between px-4 py-2">
          <div className="text-[9px] text-text-3 font-korean">
            총 {filtered.length}건 중 {(currentPage - 1) * PAGE_SIZE + 1}–{Math.min(currentPage * PAGE_SIZE, filtered.length)}
          </div>
          <div className="flex items-center gap-1">
            <button
              onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
              disabled={currentPage <= 1}
              className="px-2 py-1 rounded text-[10px] font-mono cursor-pointer border transition-colors"
              style={{ background: 'var(--bg3)', borderColor: 'var(--bd)', color: currentPage <= 1 ? 'var(--t3)' : 'var(--t1)', opacity: currentPage <= 1 ? 0.5 : 1 }}
            >◀</button>
            {Array.from({ length: totalPages }, (_, i) => i + 1).map(p => (
              <button
                key={p}
                onClick={() => setCurrentPage(p)}
                className="w-7 h-7 rounded text-[10px] font-bold font-mono cursor-pointer border transition-colors"
                style={currentPage === p
                  ? { background: 'rgba(59,130,246,.15)', borderColor: 'rgba(59,130,246,.3)', color: 'var(--blue)' }
                  : { background: 'var(--bg3)', borderColor: 'var(--bd)', color: 'var(--t3)' }
                }
              >{p}</button>
            ))}
            <button
              onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
              disabled={currentPage >= totalPages}
              className="px-2 py-1 rounded text-[10px] font-mono cursor-pointer border transition-colors"
              style={{ background: 'var(--bg3)', borderColor: 'var(--bd)', color: currentPage >= totalPages ? 'var(--t3)' : 'var(--t1)', opacity: currentPage >= totalPages ? 0.5 : 1 }}
            >▶</button>
          </div>
        </div>
      </div>

      {/* 위성 궤도 정보 */}
      <div className="grid grid-cols-2 gap-3.5">
        {/* 가용 위성 현황 */}
        <div className="bg-bg-2 border border-border rounded-md p-4">
          <div className="text-xs font-bold text-text-1 font-korean mb-3">🛰 가용 위성 현황</div>
          <div className="flex flex-col gap-2">
            {satellites.map((sat, i) => (
              <div key={i} className="flex items-center gap-2.5 px-3 py-2 bg-bg-3 rounded-md" style={{ border: `1px solid ${sat.borderColor}` }}>
                <div className={`w-2 h-2 rounded-full shrink-0 ${sat.pulse ? 'animate-pulse' : ''}`} style={{ background: sat.statusColor }} />
                <div className="flex-1">
                  <div className="text-[11px] font-semibold text-text-1 font-korean">{sat.name}</div>
                  <div className="text-[9px] text-text-3 font-korean">{sat.desc}</div>
                </div>
                <div className="text-[10px] font-bold font-korean" style={{ color: sat.statusColor }}>{sat.status}</div>
              </div>
            ))}
          </div>
        </div>

        {/* 오늘 촬영 가능 시간 */}
        <div className="bg-bg-2 border border-border rounded-md p-4">
          <div className="text-xs font-bold text-text-1 font-korean mb-3">⏰ 오늘 촬영 가능 시간 (KST)</div>
          <div className="flex flex-col gap-1.5">
            {passSchedules.map((ps, i) => (
              <div
                key={i}
                className="flex items-center gap-2 px-2.5 py-[7px] rounded-[5px]"
                style={{
                  background: ps.today ? 'rgba(34,197,94,.05)' : 'rgba(59,130,246,.05)',
                  border: ps.today ? '1px solid rgba(34,197,94,.15)' : '1px solid rgba(59,130,246,.15)',
                }}
              >
                <span className="text-[10px] font-bold font-mono min-w-[90px]" style={{ color: ps.today ? 'var(--cyan)' : 'var(--blue)' }}>{ps.time}</span>
                <span className="text-[10px] text-text-1 font-korean">{ps.desc}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
      </>)}

      {/* ═══ 촬영 히스토리 지도 뷰 ═══ */}
      {mainTab === 'map' && (() => {
        const dateFiltered = requests.filter(r => r.dateKey === mapSelectedDate)
        const dateHasDots = [...new Set(requests.map(r => r.dateKey).filter(Boolean))]
        return (
        <div className="bg-bg-2 border border-border rounded-md overflow-hidden relative" style={{ height: 'calc(100vh - 160px)' }}>
          <Map
            initialViewState={{ longitude: 127.5, latitude: 34.5, zoom: 7 }}
            mapStyle={SAT_MAP_STYLE}
            style={{ width: '100%', height: '100%' }}
            attributionControl={false}
          >
            {/* 선택된 날짜의 촬영 구역 폴리곤 */}
            {dateFiltered.map(r => {
              const coord = parseCoord(r.zoneCoord)
              if (!coord) return null
              const areaKm = parseFloat(r.zoneArea) || 10
              const delta = Math.sqrt(areaKm) * 0.005
              const isSelected = mapSelectedItem?.id === r.id
              const statusColor = r.status === '촬영중' ? '#eab308' : r.status === '완료' ? '#22c55e' : r.status === '취소' ? '#ef4444' : '#3b82f6'
              return (
                <Source key={r.id} id={`zone-${r.id}`} type="geojson" data={{
                  type: 'Feature', properties: {},
                  geometry: { type: 'Polygon', coordinates: [[
                    [coord.lon - delta, coord.lat - delta],
                    [coord.lon + delta, coord.lat - delta],
                    [coord.lon + delta, coord.lat + delta],
                    [coord.lon - delta, coord.lat + delta],
                    [coord.lon - delta, coord.lat - delta],
                  ]] },
                }}>
                  <Layer id={`zone-fill-${r.id}`} type="fill" paint={{ 'fill-color': statusColor, 'fill-opacity': isSelected ? 0.35 : 0.12 }} />
                  <Layer id={`zone-line-${r.id}`} type="line" paint={{ 'line-color': statusColor, 'line-width': isSelected ? 3 : 1.5 }} />
                </Source>
              )
            })}

            {/* 선택된 완료 항목: VWorld 위성 영상 오버레이 (BlackSky 스타일) */}
            {mapSelectedItem && mapSelectedItem.status === '완료' && satShowOverlay && VWORLD_API_KEY && (
              <Source
                id="sat-vworld-overlay"
                type="raster"
                tiles={[`https://api.vworld.kr/req/wmts/1.0.0/${VWORLD_API_KEY}/Satellite/{z}/{y}/{x}.jpeg`]}
                tileSize={256}
              >
                <Layer id="sat-vworld-layer" type="raster" paint={{
                  'raster-opacity': satImgOpacity / 100,
                  'raster-brightness-max': Math.min(satImgBrightness / 100 * 1.2, 1),
                  'raster-brightness-min': Math.max((satImgBrightness - 100) / 200, 0),
                }} />
              </Source>
            )}

            {/* 선택된 항목 마커 */}
            {mapSelectedItem && (() => {
              const coord = parseCoord(mapSelectedItem.zoneCoord)
              if (!coord) return null
              return (
                <Marker longitude={coord.lon} latitude={coord.lat} anchor="center">
                  <div className="relative">
                    <div className="w-4 h-4 rounded-full" style={{ background: 'rgba(6,182,212,.6)', border: '2px solid #fff', boxShadow: '0 0 12px rgba(6,182,212,.5)' }} />
                    <div className="absolute inset-0 w-4 h-4 rounded-full animate-ping" style={{ background: 'rgba(6,182,212,.3)' }} />
                  </div>
                </Marker>
              )
            })()}
          </Map>

          {/* 좌상단: 캘린더 + 날짜별 리스트 */}
          <div className="absolute top-3 left-3 w-[260px] rounded-lg border border-border z-10 overflow-hidden" style={{ background: 'rgba(18,25,41,.92)', backdropFilter: 'blur(8px)' }}>
            {/* 캘린더 헤더 */}
            <div className="px-3 py-2 border-b border-border">
              <div className="text-[10px] font-bold text-text-2 font-korean mb-2">📅 촬영 날짜 선택</div>
              <input
                type="date"
                value={mapSelectedDate}
                onChange={e => { setMapSelectedDate(e.target.value); setMapSelectedItem(null) }}
                className="w-full px-2.5 py-1.5 bg-bg-3 border border-border rounded text-[11px] font-mono text-text-1 outline-none focus:border-[var(--cyan)] transition-colors"
              />
              {/* 촬영 이력 있는 날짜 점 표시 */}
              <div className="flex flex-wrap gap-1 mt-2">
                {dateHasDots.map(d => (
                  <button
                    key={d}
                    onClick={() => { setMapSelectedDate(d!); setMapSelectedItem(null) }}
                    className="px-1.5 py-0.5 rounded text-[8px] font-mono cursor-pointer border transition-colors"
                    style={mapSelectedDate === d
                      ? { background: 'rgba(6,182,212,.2)', borderColor: 'var(--cyan)', color: 'var(--cyan)' }
                      : { background: 'var(--bg0)', borderColor: 'var(--bd)', color: 'var(--t3)' }
                    }
                  >{d?.slice(5)}</button>
                ))}
              </div>
            </div>

            {/* 날짜별 촬영 리스트 */}
            <div className="max-h-[35vh] overflow-y-auto" style={{ scrollbarWidth: 'thin', scrollbarColor: 'var(--bdL) transparent' }}>
              <div className="px-3 py-1.5 border-b border-border text-[9px] text-text-3 font-korean sticky top-0" style={{ background: 'rgba(18,25,41,.95)' }}>
                {mapSelectedDate} · {dateFiltered.length}건
              </div>
              {dateFiltered.length === 0 ? (
                <div className="px-3 py-4 text-[10px] text-text-3 font-korean text-center">이 날짜에 촬영 이력이 없습니다</div>
              ) : dateFiltered.map(r => {
                const statusColor = r.status === '촬영중' ? '#eab308' : r.status === '완료' ? '#22c55e' : r.status === '취소' ? '#ef4444' : '#3b82f6'
                const isSelected = mapSelectedItem?.id === r.id
                return (
                  <div
                    key={r.id}
                    onClick={() => setMapSelectedItem(isSelected ? null : r)}
                    className="px-3 py-2 border-b cursor-pointer transition-colors"
                    style={{
                      borderColor: 'rgba(255,255,255,.04)',
                      background: isSelected ? 'rgba(6,182,212,.1)' : 'transparent',
                    }}
                  >
                    <div className="flex items-center justify-between mb-0.5">
                      <span className="text-[10px] font-mono text-text-2">{r.id}</span>
                      <span className="text-[8px] font-bold px-1.5 py-px rounded-full" style={{ background: `${statusColor}20`, color: statusColor }}>{r.status}</span>
                    </div>
                    <div className="text-[9px] text-text-1 font-korean truncate">{r.zone}</div>
                    <div className="text-[8px] text-text-3 font-mono mt-0.5">{r.satellite} · {r.resolution}</div>
                    {r.status === '완료' && (
                      <div className="mt-1 text-[8px] font-korean" style={{ color: 'var(--cyan)' }}>📷 클릭하여 영상 보기</div>
                    )}
                  </div>
                )
              })}
            </div>
          </div>

          {/* 우상단: 범례 */}
          <div className="absolute top-3 right-3 px-3 py-2.5 rounded-lg border border-border z-10" style={{ background: 'rgba(18,25,41,.9)', backdropFilter: 'blur(8px)' }}>
            <div className="text-[10px] font-bold text-text-2 font-korean mb-2">촬영 이력</div>
            {[
              { label: '촬영중', color: '#eab308' },
              { label: '대기', color: '#3b82f6' },
              { label: '완료', color: '#22c55e' },
              { label: '취소', color: '#ef4444' },
            ].map(item => (
              <div key={item.label} className="flex items-center gap-2 mb-1">
                <div className="w-3 h-3 rounded-sm" style={{ background: item.color, opacity: 0.4, border: `1px solid ${item.color}` }} />
                <span className="text-[9px] text-text-3 font-korean">{item.label}</span>
              </div>
            ))}
            <div className="text-[8px] text-text-3 font-korean mt-1.5 pt-1.5 border-t border-border">총 {requests.length}건</div>
          </div>

          {/* 선택된 항목 상세 (하단) */}
          {mapSelectedItem && (
            <div className="absolute bottom-3 left-1/2 -translate-x-1/2 px-4 py-3 rounded-lg border border-border z-10 max-w-[500px]" style={{ background: 'rgba(18,25,41,.95)', backdropFilter: 'blur(8px)' }}>
              <div className="flex items-center gap-3">
                <div className="flex-1">
                  <div className="text-[11px] font-bold text-text-1 font-korean mb-0.5">{mapSelectedItem.zone}</div>
                  <div className="text-[9px] text-text-3 font-mono">{mapSelectedItem.satellite} · {mapSelectedItem.resolution} · {mapSelectedItem.zoneCoord}</div>
                </div>
                <div className="text-center shrink-0">
                  <div className="text-[8px] text-text-3 font-korean">요청</div>
                  <div className="text-[10px] font-mono text-text-1">{mapSelectedItem.requestDate}</div>
                </div>
                {mapSelectedItem.status === '완료' && (
                  <div className="px-2 py-1 rounded text-[9px] font-bold font-korean shrink-0" style={{ background: 'rgba(34,197,94,.15)', color: '#22c55e' }}>
                    📷 영상 표출중
                  </div>
                )}
                <button onClick={() => setMapSelectedItem(null)} className="text-text-3 bg-transparent border-none cursor-pointer text-sm">✕</button>
              </div>
            </div>
          )}
        </div>
        )
      })()}

      {/* ═══ 모달: 제공자 선택 ═══ */}
      {modalPhase !== 'none' && (
        <div className="fixed inset-0 z-[9999] flex items-center justify-center" style={{ background: 'rgba(5,8,18,.75)', backdropFilter: 'blur(8px)' }}>
          <div ref={modalRef}>

            {/* ── 제공자 선택 ── */}
            {modalPhase === 'provider' && (
              <div className="border rounded-2xl w-[640px] overflow-hidden" style={{ background: 'var(--bg1)', borderColor: 'rgba(99,102,241,.3)', boxShadow: '0 24px 80px rgba(0,0,0,.6)' }}>
                {/* 헤더 */}
                <div className="px-7 pt-6 pb-4 relative overflow-hidden">
                  <div className="absolute top-0 left-0 right-0 h-0.5" style={{ background: 'linear-gradient(90deg,#6366f1,#3b82f6,#06b6d4)' }} />
                  <div className="flex items-center justify-between">
                    <div className="flex items-center gap-3">
                      <div className="w-10 h-10 rounded-xl flex items-center justify-center text-xl" style={{ background: 'linear-gradient(135deg,rgba(99,102,241,.15),rgba(59,130,246,.08))' }}>🛰</div>
                      <div>
                        <div className="text-base font-bold text-text-1 font-korean">위성 촬영 요청 — 제공자 선택</div>
                        <div className="text-[10px] text-text-3 font-korean mt-0.5">요청할 위성 서비스 제공자를 선택하세요</div>
                      </div>
                    </div>
                    <button onClick={() => setModalPhase('none')} className="text-lg cursor-pointer text-text-3 p-1 bg-transparent border-none hover:text-text-1 transition-colors">✕</button>
                  </div>
                </div>

                {/* 제공자 카드 */}
                <div className="px-7 pb-6 flex flex-col gap-3.5">
                  {/* BlackSky (Maxar) */}
                  <div
                    onClick={() => setModalPhase('blacksky')}
                    className="cursor-pointer bg-bg-2 border border-border rounded-xl p-5 relative overflow-hidden hover:border-[rgba(99,102,241,.5)] hover:bg-[rgba(99,102,241,.04)] transition-all"
                  >
                    <div className="flex items-center justify-between mb-3">
                      <div className="flex items-center gap-2.5">
                        <div className="w-[42px] h-[42px] rounded-[10px] flex items-center justify-center border border-[rgba(99,102,241,.3)]" style={{ background: 'linear-gradient(135deg,#1a1a2e,#16213e)' }}>
                          <span className="text-[11px] font-extrabold font-mono text-[#818cf8] tracking-[-0.5px]">B<span className="text-[#a78bfa]">Sky</span></span>
                        </div>
                        <div>
                          <div className="text-sm font-bold text-text-1 font-korean">BlackSky</div>
                          <div className="text-[9px] text-text-3 font-korean mt-px">Maxar Electro-Optical API</div>
                        </div>
                      </div>
                      <div className="flex items-center gap-1.5">
                        <span className="px-2 py-0.5 rounded-[10px] text-[8px] font-semibold text-green-500" style={{ background: 'rgba(34,197,94,.1)', border: '1px solid rgba(34,197,94,.2)' }}>API 연결됨</span>
                        <span className="text-base text-text-3">→</span>
                      </div>
                    </div>
                    <div className="grid grid-cols-4 gap-2 mb-2.5">
                      {[
                        ['유형', 'EO (광학)', '#818cf8'],
                        ['해상도', '~1m', 'var(--t1)'],
                        ['재방문', '≤1시간', 'var(--t1)'],
                        ['납기', '90분 이내', '#22c55e'],
                      ].map(([k, v, c], i) => (
                        <div key={i} className="text-center p-1.5 bg-bg-0 rounded-md">
                          <div className="text-[7px] text-text-3 font-korean mb-0.5">{k}</div>
                          <div className="text-[10px] font-bold font-mono" style={{ color: c }}>{v}</div>
                        </div>
                      ))}
                    </div>
                    <div className="text-[9px] text-text-3 font-korean leading-relaxed">고빈도 소형위성 군집 기반 긴급 촬영. 해양 사고 현장 신속 모니터링에 최적화. Dawn-to-Dusk 촬영 가능.</div>
                    <div className="mt-2 text-[8px] text-text-3 font-mono">API: <span className="text-[#818cf8]">eapi.maxar.com/e1so/rapidoc</span></div>
                  </div>

                  {/* UP42 (EO + SAR) */}
                  <div
                    onClick={() => setModalPhase('up42')}
                    className="cursor-pointer bg-bg-2 border border-border rounded-xl p-5 relative overflow-hidden hover:border-[rgba(59,130,246,.5)] hover:bg-[rgba(59,130,246,.04)] transition-all"
                  >
                    <div className="flex items-center justify-between mb-3">
                      <div className="flex items-center gap-2.5">
                        <div className="w-[42px] h-[42px] rounded-[10px] flex items-center justify-center border border-[rgba(59,130,246,.3)]" style={{ background: 'linear-gradient(135deg,#0a1628,#162a50)' }}>
                          <span className="text-[13px] font-extrabold font-mono text-[#60a5fa] tracking-[-0.5px]">up<sup className="text-[7px] align-super">42</sup></span>
                        </div>
                        <div>
                          <div className="text-sm font-bold text-text-1 font-korean">UP42 — EO + SAR</div>
                          <div className="text-[9px] text-text-3 font-korean mt-px">Optical · SAR · Elevation 통합 마켓플레이스</div>
                        </div>
                      </div>
                      <div className="flex items-center gap-1.5">
                        <span className="px-2 py-0.5 rounded-[10px] text-[8px] font-semibold text-green-500" style={{ background: 'rgba(34,197,94,.1)', border: '1px solid rgba(34,197,94,.2)' }}>API 연결됨</span>
                        <span className="text-base text-text-3">→</span>
                      </div>
                    </div>
                    <div className="grid grid-cols-4 gap-2 mb-2.5">
                      {[
                        ['유형', 'EO + SAR', '#60a5fa'],
                        ['해상도', '0.3~5m', 'var(--t1)'],
                        ['위성 수', '16+ 컬렉션', 'var(--t1)'],
                        ['야간/악천후', 'SAR 가능', '#22c55e'],
                      ].map(([k, v, c], i) => (
                        <div key={i} className="text-center p-1.5 bg-bg-0 rounded-md">
                          <div className="text-[7px] text-text-3 font-korean mb-0.5">{k}</div>
                          <div className="text-[10px] font-bold font-mono" style={{ color: c }}>{v}</div>
                        </div>
                      ))}
                    </div>
                    <div className="flex gap-1.5 mb-2.5 flex-wrap">
                      {['Pléiades Neo', 'SPOT 6/7'].map((t, i) => (
                        <span key={i} className="px-1.5 py-px rounded text-[8px] font-korean text-[#60a5fa]" style={{ background: 'rgba(59,130,246,.08)', border: '1px solid rgba(59,130,246,.15)' }}>{t}</span>
                      ))}
                      {['TerraSAR-X', 'Capella SAR', 'ICEYE'].map((t, i) => (
                        <span key={i} className="px-1.5 py-px rounded text-[8px] font-korean" style={{ background: 'rgba(6,182,212,.08)', border: '1px solid rgba(6,182,212,.15)', color: 'var(--cyan)' }}>{t}</span>
                      ))}
                      <span className="px-1.5 py-px rounded text-[8px] font-korean" style={{ background: 'rgba(139,148,158,.08)', border: '1px solid rgba(139,148,158,.15)', color: 'var(--t3)' }}>+11 more</span>
                    </div>
                    <div className="text-[9px] text-text-3 font-korean leading-relaxed">광학(EO) + 합성개구레이더(SAR) 통합 마켓. 야간·악천후 시 SAR 활용. 다중 위성 소스 자동 최적 선택.</div>
                    <div className="mt-2 text-[8px] text-text-3 font-mono">API: <span className="text-[#60a5fa]">up42.com</span></div>
                  </div>
                </div>

                {/* 하단 */}
                <div className="px-7 pb-5 flex items-center justify-between">
                  <div className="text-[9px] text-text-3 font-korean leading-relaxed">💡 긴급 촬영: BlackSky 권장 (90분 납기) · 야간/악천후: UP42 SAR 권장</div>
                  <button onClick={() => setModalPhase('none')} className="px-4 py-2 rounded-lg border text-[11px] font-semibold cursor-pointer font-korean bg-bg-3 text-text-2 border-border">닫기</button>
                </div>
              </div>
            )}

            {/* ── BlackSky 긴급 촬영 요청 ── */}
            {modalPhase === 'blacksky' && (
              <div className="border rounded-[14px] w-[860px] max-h-[90vh] flex flex-col overflow-hidden border-[rgba(99,102,241,.3)]" style={{ background: '#0d1117', boxShadow: '0 24px 80px rgba(0,0,0,.7)' }}>
                {/* 헤더 */}
                <div className="px-6 py-4 border-b border-[#21262d] flex items-center justify-between shrink-0 relative">
                  <div className="absolute top-0 left-0 right-0 h-0.5" style={{ background: 'linear-gradient(90deg,#6366f1,#818cf8,#a78bfa)' }} />
                  <div className="flex items-center gap-3">
                    <div className="w-9 h-9 rounded-lg flex items-center justify-center border border-[rgba(99,102,241,.3)]" style={{ background: 'linear-gradient(135deg,#1a1a2e,#16213e)' }}>
                      <span className="text-[10px] font-extrabold font-mono text-[#818cf8]">B<span className="text-[#a78bfa]">Sky</span></span>
                    </div>
                    <div>
                      <div className="text-[15px] font-bold font-korean text-[#e2e8f0]">BlackSky — 긴급 위성 촬영 요청</div>
                      <div className="text-[9px] font-korean mt-0.5 text-[#64748b]">Maxar E1SO RapiDoc API · 고빈도 긴급 태스킹</div>
                    </div>
                  </div>
                  <div className="flex items-center gap-2">
                    <span className="px-3 py-1 rounded-md text-[9px] font-semibold font-korean text-[#818cf8]" style={{ background: 'rgba(99,102,241,.1)', border: '1px solid rgba(99,102,241,.25)' }}>API Docs ↗</span>
                    <button onClick={() => setModalPhase('none')} className="text-lg cursor-pointer p-1 bg-transparent border-none text-[#64748b]">✕</button>
                  </div>
                </div>

                {/* 본문 */}
                <div className="flex-1 overflow-y-auto px-6 py-5 flex flex-col gap-4" style={{ scrollbarWidth: 'thin', scrollbarColor: '#21262d transparent' }}>
                  {/* API 상태 */}
                  <div className="flex items-center gap-2.5 px-3.5 py-2.5 rounded-lg" style={{ background: 'rgba(34,197,94,.06)', border: '1px solid rgba(34,197,94,.15)' }}>
                    <div className="w-2 h-2 rounded-full" style={{ background: '#22c55e', boxShadow: '0 0 6px rgba(34,197,94,.5)' }} />
                    <span className="text-[10px] font-semibold font-korean text-green-500">API Connected</span>
                    <span className="text-[9px] font-mono text-[#64748b]">eapi.maxar.com/e1so/rapidoc · Latency: 142ms</span>
                    <span className="ml-auto text-[8px] font-mono text-[#64748b]">Quota: 47/50 요청 잔여</span>
                  </div>

                  {/* ① 태스킹 유형 */}
                  <div>
                    {sectionHeader(1, '태스킹 유형 · 우선순위')}
                    <div className="grid grid-cols-3 gap-2.5">
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">촬영 유형 <span className="text-red-400">*</span></label>
                        <select className={bsInput} style={bsInputStyle}>
                          <option>긴급 태스킹 (Emergency)</option>
                          <option>표준 태스킹 (Standard)</option>
                          <option>아카이브 검색 (Archive)</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">우선순위 <span className="text-red-400">*</span></label>
                        <select className={bsInput} style={bsInputStyle}>
                          <option>P1 — 긴급 (90분 내)</option>
                          <option>P2 — 높음 (6시간 내)</option>
                          <option>P3 — 보통 (24시간 내)</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">촬영 모드</label>
                        <select className={bsInput} style={bsInputStyle}>
                          <option>Single Collect</option>
                          <option>Multi-pass Monitoring</option>
                          <option>Continuous (매 패스)</option>
                        </select>
                      </div>
                    </div>
                  </div>

                  {/* ② AOI 지정 */}
                  <div>
                    {sectionHeader(2, '관심 영역 (AOI)')}
                    <div className="grid grid-cols-3 gap-2.5 items-end">
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">중심 위도 <span className="text-red-400">*</span></label>
                        <input type="text" defaultValue="34.5832" className={bsInput} style={bsInputStyle} />
                      </div>
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">중심 경도 <span className="text-red-400">*</span></label>
                        <input type="text" defaultValue="128.4217" className={bsInput} style={bsInputStyle} />
                      </div>
                      <button className="px-3.5 py-2 rounded-md text-[10px] font-semibold cursor-pointer font-korean whitespace-nowrap text-[#818cf8]" style={{ border: '1px solid rgba(99,102,241,.3)', background: 'rgba(99,102,241,.08)' }}>📍 지도에서 AOI 그리기</button>
                    </div>
                    <div className="mt-2 grid grid-cols-3 gap-2.5">
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">AOI 반경 (km)</label>
                        <input type="number" defaultValue={10} step={1} min={1} className={bsInput} style={bsInputStyle} />
                      </div>
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">최대 구름량 (%)</label>
                        <input type="number" defaultValue={20} step={5} min={0} max={100} className={bsInput} style={bsInputStyle} />
                      </div>
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">최대 Off-nadir (°)</label>
                        <input type="number" defaultValue={25} step={5} min={0} max={45} className={bsInput} style={bsInputStyle} />
                      </div>
                    </div>
                  </div>

                  {/* ③ 촬영 기간 */}
                  <div>
                    {sectionHeader(3, '촬영 기간 · 반복')}
                    <div className="grid grid-cols-3 gap-2.5">
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">촬영 시작 <span className="text-red-400">*</span></label>
                        <input type="datetime-local" defaultValue="2026-02-26T08:00" className={bsInput} style={bsInputStyle} />
                      </div>
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">촬영 종료 <span className="text-red-400">*</span></label>
                        <input type="datetime-local" defaultValue="2026-02-27T20:00" className={bsInput} style={bsInputStyle} />
                      </div>
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">반복 촬영</label>
                        <select className={bsInput} style={bsInputStyle}>
                          <option>1회 (단일)</option>
                          <option>매 패스 (가용 시)</option>
                          <option>매 6시간</option>
                          <option>매 12시간</option>
                          <option>매일 1회</option>
                        </select>
                      </div>
                    </div>
                  </div>

                  {/* ④ 산출물 설정 */}
                  <div>
                    {sectionHeader(4, '산출물 설정')}
                    <div className="grid grid-cols-2 gap-2.5">
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">산출물 형식 <span className="text-red-400">*</span></label>
                        <select className={bsInput} style={bsInputStyle}>
                          <option>Ortho-Rectified (정사보정)</option>
                          <option>Pan-sharpened (팬샤프닝)</option>
                          <option>Basic L1 (원본)</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">파일 포맷</label>
                        <select className={bsInput} style={bsInputStyle}>
                          <option>GeoTIFF</option>
                          <option>NITF</option>
                          <option>JPEG2000</option>
                        </select>
                      </div>
                    </div>
                    <div className="mt-2 flex flex-wrap gap-3">
                      {[
                        { label: '유출유 탐지 분석 (자동)', checked: true },
                        { label: 'GIS 상황판 자동 오버레이', checked: true },
                        { label: '변화탐지 (Change Detection)', checked: false },
                        { label: '웹훅 알림', checked: false },
                      ].map((opt, i) => (
                        <label key={i} className="flex items-center gap-1 text-[9px] cursor-pointer font-korean text-[#94a3b8]">
                          <input type="checkbox" defaultChecked={opt.checked} style={{ accentColor: '#818cf8', transform: 'scale(.85)' }} /> {opt.label}
                        </label>
                      ))}
                    </div>
                  </div>

                  {/* ⑤ 연계 사고 · 비고 */}
                  <div>
                    {sectionHeader(5, '연계 사고 · 비고')}
                    <div className="grid grid-cols-2 gap-2.5 mb-2">
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">연계 사고번호</label>
                        <select className={bsInput} style={bsInputStyle}>
                          <option>OIL-2024-0892 · M/V STELLAR DAISY</option>
                          <option>HNS-2024-041 · 울산 온산항 톨루엔 유출</option>
                          <option>RSC-2024-0127 · M/V SEA GUARDIAN</option>
                          <option value="">연계 없음</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-[9px] font-korean mb-1 text-[#64748b]">요청자</label>
                        <input type="text" placeholder="소속 / 이름" className={bsInput} style={bsInputStyle} />
                      </div>
                    </div>
                    <textarea
                      placeholder="촬영 요청 목적, 특이사항, 관심 대상 등을 기록합니다..."
                      className="w-full h-[50px] px-3 py-2.5 rounded-md text-[10px] font-korean outline-none resize-y leading-relaxed box-border border border-[#21262d] text-[#e2e8f0] bg-[#161b22]"
                    />
                  </div>
                </div>

                {/* 하단 버튼 */}
                <div className="px-6 py-3.5 border-t border-[#21262d] flex items-center gap-2 shrink-0">
                  <div className="flex-1 text-[9px] font-korean leading-relaxed text-[#64748b]">
                    <span className="text-red-400">*</span> 필수 항목 · 긴급 태스킹은 P1 우선순위로 90분 내 최초 영상 수신
                  </div>
                  <button onClick={() => setModalPhase('provider')} className="px-5 py-2.5 rounded-lg border border-[#21262d] text-xs font-semibold cursor-pointer font-korean text-[#94a3b8] bg-[#161b22]">← 뒤로</button>
                  <button onClick={() => setModalPhase('none')} className="px-7 py-2.5 rounded-lg border-none text-xs font-bold cursor-pointer font-korean text-white" style={{ background: 'linear-gradient(135deg,#6366f1,#818cf8)', boxShadow: '0 4px 16px rgba(99,102,241,.35)' }}>🛰 BlackSky 촬영 요청 제출</button>
                </div>
              </div>
            )}

            {/* ── UP42 카탈로그 주문 ── */}
            {modalPhase === 'up42' && (
              <div className="border rounded-[14px] w-[920px] flex flex-col overflow-hidden border-[rgba(59,130,246,.3)]" style={{ background: '#0d1117', boxShadow: '0 24px 80px rgba(0,0,0,.7)', height: '85vh' }}>
                {/* 헤더 */}
                <div className="px-6 py-4 border-b border-[#21262d] flex items-center justify-between shrink-0 relative">
                  <div className="absolute top-0 left-0 right-0 h-0.5" style={{ background: 'linear-gradient(90deg,#3b82f6,#06b6d4,#22c55e)' }} />
                  <div className="flex items-center gap-3">
                    <div className="w-9 h-9 rounded-lg flex items-center justify-center border border-[rgba(59,130,246,.3)]" style={{ background: 'linear-gradient(135deg,#0a1628,#162a50)' }}>
                      <span className="text-[13px] font-extrabold font-mono text-[#60a5fa] tracking-[-0.5px]">up<sup className="text-[7px] align-super">42</sup></span>
                    </div>
                    <div>
                      <div className="text-[15px] font-bold font-korean text-[#e2e8f0]">위성 촬영 요청 — 새 태스킹 주문</div>
                      <div className="text-[9px] font-korean mt-0.5 text-[#64748b]">관심 지역(AOI)을 그리고 위성 패스를 선택하세요</div>
                    </div>
                  </div>
                  <div className="flex items-center gap-2">
                    <span className="px-3 py-1 rounded-full text-[10px] font-semibold font-korean" style={{ background: 'rgba(234,179,8,.1)', border: '1px solid rgba(234,179,8,.25)', color: '#eab308' }}>⚠ Beijing-3N 납기 지연 2.15–2.23</span>
                    <button onClick={() => setModalPhase('none')} className="text-lg cursor-pointer p-1 bg-transparent border-none text-[#64748b]">✕</button>
                  </div>
                </div>

                {/* 본문 (좌: 사이드바, 우: 지도+AOI) */}
                <div className="flex-1 flex overflow-hidden">
                  {/* 왼쪽: 위성 카탈로그 */}
                  <div className="flex flex-col overflow-hidden border-r border-[#21262d]" style={{ width: 320, minWidth: 320, background: '#0d1117' }}>
                    {/* Optical / SAR / Elevation 탭 */}
                    <div className="flex border-b border-[#21262d] shrink-0">
                      {(['optical', 'sar', 'elevation'] as const).map(t => (
                        <button
                          key={t}
                          onClick={() => setUp42SubTab(t)}
                          className="flex-1 py-2 text-[10px] font-bold cursor-pointer border-none font-korean transition-colors"
                          style={up42SubTab === t
                            ? { background: 'rgba(59,130,246,.1)', color: '#60a5fa', borderBottom: '2px solid #3b82f6' }
                            : { background: 'transparent', color: '#64748b' }
                          }
                        >{t === 'optical' ? 'Optical' : t === 'sar' ? 'SAR' : 'Elevation'}</button>
                      ))}
                    </div>

                    {/* 필터 바 */}
                    <div className="flex items-center gap-1.5 px-3 py-2 border-b border-[#21262d] shrink-0">
                      <span className="px-2 py-0.5 rounded text-[9px] font-semibold text-[#60a5fa]" style={{ background: 'rgba(59,130,246,.1)', border: '1px solid rgba(59,130,246,.2)' }}>Filters ✎</span>
                      <span className="px-2 py-0.5 rounded text-[9px] font-semibold text-[#818cf8]" style={{ background: 'rgba(99,102,241,.1)', border: '1px solid rgba(99,102,241,.2)' }}>☁ 구름 ≤ 20% ✕</span>
                      <span className="ml-auto text-[9px] font-mono text-[#64748b]">↕ 해상도 우선</span>
                    </div>

                    {/* 컬렉션 수 */}
                    <div className="px-3 py-1.5 border-b border-[#21262d] text-[9px] font-korean shrink-0 text-[#64748b]">
                      이 지역에서 <b className="text-[#e2e8f0]">{up42Filtered.length}</b>개 컬렉션 사용 가능
                    </div>

                    {/* 위성 목록 */}
                    <div className="flex-1 overflow-y-auto" style={{ scrollbarWidth: 'thin', scrollbarColor: '#21262d transparent' }}>
                      {up42Filtered.map(sat => (
                        <div
                          key={sat.id}
                          onClick={() => setUp42SelSat(up42SelSat === sat.id ? null : sat.id)}
                          className="flex items-center gap-2.5 px-3 py-2.5 border-b border-[#161b22] cursor-pointer transition-colors"
                          style={{
                            background: up42SelSat === sat.id ? 'rgba(59,130,246,.08)' : 'transparent',
                          }}
                        >
                          <div className="w-1 h-8 rounded-full shrink-0" style={{ background: sat.color }} />
                          <div className="flex-1 min-w-0">
                            <div className="text-[11px] font-semibold truncate font-korean text-[#e2e8f0]">{sat.name}</div>
                            <div className="flex items-center gap-2 mt-0.5">
                              <span className="text-[9px] font-bold font-mono" style={{ color: sat.color }}>{sat.res}</span>
                              {sat.cloud > 0 && <span className="text-[8px] font-mono text-[#64748b]">☁ ≤{sat.cloud}%</span>}
                              {'delay' in sat && sat.delay && <span className="text-[8px] font-bold" style={{ color: '#eab308' }}>⚠ 지연</span>}
                            </div>
                          </div>
                          {up42SelSat === sat.id && <span className="text-[12px] text-blue-500">✓</span>}
                        </div>
                      ))}
                    </div>
                  </div>

                  {/* 오른쪽: 궤도 지도 + 패스 목록 */}
                  <div className="flex-1 flex flex-col overflow-hidden min-w-0">
                    {/* 지도 영역 — 위성 궤도 표시 (최소 높이 보장) */}
                    <div className="flex-1 relative" style={{ minHeight: 350 }}>
                      <Map
                        initialViewState={{ longitude: 128, latitude: 36, zoom: 5.5 }}
                        mapStyle={SAT_MAP_STYLE}
                        style={{ width: '100%', height: '100%' }}
                        attributionControl={false}
                      >
                        {/* 한국 영역 AOI 박스 */}
                        <Source id="korea-aoi" type="geojson" data={{
                          type: 'Feature',
                          properties: {},
                          geometry: { type: 'Polygon', coordinates: [[[124, 33], [132, 33], [132, 39], [124, 39], [124, 33]]] },
                        }}>
                          <Layer id="korea-aoi-fill" type="fill" paint={{ 'fill-color': '#3b82f6', 'fill-opacity': 0.05 }} />
                          <Layer id="korea-aoi-line" type="line" paint={{ 'line-color': '#3b82f6', 'line-width': 1.5, 'line-dasharray': [4, 3] }} />
                        </Source>

                        {/* 위성 궤도 라인 */}
                        {satPasses.map(pass => (
                          <Source key={pass.id} id={`orbit-${pass.id}`} type="geojson" data={{
                            type: 'Feature',
                            properties: {},
                            geometry: { type: 'LineString', coordinates: pass.orbit.map(p => [p.lon, p.lat]) },
                          }}>
                            <Layer
                              id={`orbit-line-${pass.id}`}
                              type="line"
                              paint={{
                                'line-color': pass.color,
                                'line-width': up42SelPass === pass.id ? 3 : 1.5,
                                'line-opacity': up42SelPass === pass.id ? 1 : up42SelPass ? 0.2 : 0.6,
                                'line-dasharray': pass.type === 'sar' ? [6, 4] : [1],
                              }}
                            />
                            {/* 궤도 위 위성 위치 (중간점) */}
                            {(up42SelPass === pass.id || !up42SelPass) && (
                              <Layer
                                id={`orbit-point-${pass.id}`}
                                type="circle"
                                filter={['==', '$type', 'LineString']}
                                paint={{}}
                              />
                            )}
                          </Source>
                        ))}
                      </Map>

                      {/* 범례 오버레이 */}
                      <div className="absolute top-3 left-3 px-3 py-2 rounded-lg z-10 border border-[#21262d]" style={{ background: 'rgba(13,17,23,.9)', backdropFilter: 'blur(8px)' }}>
                        <div className="text-[9px] font-bold text-[#64748b] mb-1.5">🛰 위성 궤도</div>
                        {satPasses.slice(0, 4).map(p => (
                          <div key={p.id} className="flex items-center gap-1.5 mb-1">
                            <div className="w-3 h-[2px] rounded-sm" style={{ background: p.color }} />
                            <span className="text-[8px] text-[#94a3b8]">{p.satellite}</span>
                          </div>
                        ))}
                        <div className="flex items-center gap-1.5 mt-1.5 pt-1.5 border-t border-[#21262d]">
                          <div className="w-3 h-3 rounded border border-[#3b82f6]" style={{ background: 'rgba(59,130,246,.1)' }} />
                          <span className="text-[8px] text-[#64748b]">한국 영역 AOI</span>
                        </div>
                      </div>

                      {/* 로딩 */}
                      {satPassesLoading && (
                        <div className="absolute inset-0 flex items-center justify-center z-10" style={{ background: 'rgba(0,0,0,.5)' }}>
                          <div className="text-[11px] text-[#60a5fa] font-korean animate-pulse">🛰 위성 패스 조회 중...</div>
                        </div>
                      )}
                    </div>

                    {/* 위성 패스 타임라인 */}
                    <div className="border-t border-[#21262d] px-4 py-3 shrink-0 max-h-[200px] overflow-y-auto" style={{ background: 'rgba(13,17,23,.95)', scrollbarWidth: 'thin', scrollbarColor: '#21262d transparent' }}>
                      <div className="text-[10px] font-bold font-korean mb-2 text-[#e2e8f0]">
                        🛰 한국 주변 실시간 위성 패스 ({satPasses.length}개)
                        <span className="text-[8px] text-[#64748b] font-normal ml-2">클릭하여 궤도 확인</span>
                      </div>
                      <div className="flex flex-col gap-1.5">
                        {satPasses.map(pass => {
                          const start = new Date(pass.startTime)
                          const timeStr = `${start.getHours().toString().padStart(2, '0')}:${start.getMinutes().toString().padStart(2, '0')}`
                          const diffH = Math.max(0, (start.getTime() - Date.now()) / 3600000)
                          const urgency = diffH < 3 ? '긴급' : diffH < 8 ? '예정' : '내일'
                          return (
                            <div
                              key={pass.id}
                              onClick={() => setUp42SelPass(up42SelPass === pass.id ? null : pass.id)}
                              className="flex items-center gap-3 px-3 py-2 rounded-md cursor-pointer transition-colors"
                              style={{
                                background: up42SelPass === pass.id ? 'rgba(59,130,246,.1)' : '#161b22',
                                border: up42SelPass === pass.id ? `1px solid ${pass.color}40` : '1px solid #21262d',
                              }}
                            >
                              <div className="w-1.5 h-6 rounded-full shrink-0" style={{ background: pass.color }} />
                              <div className="flex-1 min-w-0">
                                <div className="flex items-center gap-2">
                                  <span className="text-[10px] font-bold font-korean text-[#e2e8f0]">{pass.satellite}</span>
                                  <span className="text-[8px] text-[#64748b]">{pass.provider}</span>
                                </div>
                                <div className="flex items-center gap-2 mt-0.5">
                                  <span className="text-[9px] font-bold font-mono text-[#60a5fa]">{timeStr}</span>
                                  <span className="text-[9px] font-mono" style={{ color: pass.color }}>{pass.resolution}</span>
                                  <span className="text-[8px] font-mono text-[#64748b]">EL {pass.maxElevation}° · {pass.direction === 'ascending' ? '↗ 상승' : '↘ 하강'}</span>
                                </div>
                              </div>
                              <span className="px-1.5 py-px rounded text-[8px] font-bold shrink-0" style={{
                                background: urgency === '긴급' ? 'rgba(239,68,68,.1)' : urgency === '예정' ? 'rgba(6,182,212,.1)' : 'rgba(100,116,139,.1)',
                                color: urgency === '긴급' ? '#ef4444' : urgency === '예정' ? '#06b6d4' : '#64748b',
                              }}>{urgency}</span>
                              {up42SelPass === pass.id && <span className="text-xs text-blue-500">✓</span>}
                            </div>
                          )
                        })}
                      </div>
                    </div>
                  </div>
                </div>

                {/* 푸터 */}
                <div className="px-6 py-3 border-t border-[#21262d] flex items-center justify-between shrink-0">
                  <div className="text-[9px] font-korean text-[#64748b]">원하는 위성을 찾지 못했나요? <span className="text-[#60a5fa] cursor-pointer">태스킹 주문 생성</span> 또는 <span className="text-[#60a5fa] cursor-pointer">자세히 보기 ↗</span></div>
                  <div className="flex items-center gap-2">
                    <span className="text-[11px] font-korean mr-1.5 text-[#8690a6]">
                      선택: {up42SelPass ? satPasses.find(p => p.id === up42SelPass)?.satellite : up42SelSat ? up42Satellites.find(s => s.id === up42SelSat)?.name : '없음'}
                    </span>
                    <button onClick={() => setModalPhase('provider')} className="px-4 py-2 rounded-lg border border-[#21262d] text-[11px] font-semibold cursor-pointer font-korean text-[#94a3b8] bg-[#161b22]">← 뒤로</button>
                    <button
                      onClick={() => setModalPhase('none')}
                      className="px-6 py-2 rounded-lg border-none text-[11px] font-bold cursor-pointer font-korean text-white transition-opacity"
                      style={{
                        background: up42SelSat ? 'linear-gradient(135deg,#3b82f6,#06b6d4)' : '#21262d',
                        opacity: up42SelSat ? 1 : 0.5,
                        color: up42SelSat ? '#fff' : '#64748b',
                        boxShadow: up42SelSat ? '0 4px 16px rgba(59,130,246,.35)' : 'none',
                      }}
                    >🛰 촬영 요청 제출</button>
                  </div>
                </div>
              </div>
            )}

          </div>
        </div>
      )}
    </div>
  )
}
