import { useState, useEffect, useRef } from 'react'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
import type { ScatSegment } from './scatTypes'
import { esiColor, jejuCoastCoords, scatDetailData } from './scatConstants'

interface ScatMapProps {
  segments: ScatSegment[]
  selectedSeg: ScatSegment
  onSelectSeg: (s: ScatSegment) => void
  onOpenPopup: (idx: number) => void
}

function ScatMap({
  segments,
  selectedSeg,
  onSelectSeg,
  onOpenPopup,
}: ScatMapProps) {
  const mapContainerRef = useRef<HTMLDivElement>(null)
  const mapRef = useRef<L.Map | null>(null)
  const markersRef = useRef<L.LayerGroup | null>(null)
  const [zoom, setZoom] = useState(10)

  useEffect(() => {
    if (!mapContainerRef.current || mapRef.current) return

    const map = L.map(mapContainerRef.current, {
      center: [33.38, 126.55],
      zoom: 10,
      zoomControl: false,
      attributionControl: false,
    })

    L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
      maxZoom: 19,
    }).addTo(map)

    L.control.zoom({ position: 'bottomright' }).addTo(map)
    L.control.attribution({ position: 'bottomleft' }).addAttribution(
      '&copy; <a href="https://www.openstreetmap.org/copyright">OSM</a> &copy; <a href="https://carto.com/">CARTO</a>'
    ).addTo(map)

    map.on('zoomend', () => setZoom(map.getZoom()))

    mapRef.current = map
    markersRef.current = L.layerGroup().addTo(map)

    setTimeout(() => map.invalidateSize(), 100)

    return () => {
      map.remove()
      mapRef.current = null
      markersRef.current = null
    }
  }, [])

  useEffect(() => {
    if (!mapRef.current || !markersRef.current) return
    markersRef.current.clearLayers()

    // 줌 기반 스케일 계수 (zoom 10=아일랜드뷰 → 14+=클로즈업)
    const zScale = Math.max(0, (zoom - 9)) / 5  // 0 at z9, 1 at z14
    const polyWeight = 1 + zScale * 4            // 1 ~ 5
    const selPolyWeight = 2 + zScale * 5         // 2 ~ 7
    const glowWeight = 4 + zScale * 14           // 4 ~ 18
    const halfLenScale = 0.15 + zScale * 0.85    // 0.15 ~ 1.0
    const markerSize = Math.round(6 + zScale * 16) // 6px ~ 22px
    const markerBorder = zoom >= 13 ? 2 : 1
    const markerFontSize = Math.round(4 + zScale * 6) // 4px ~ 10px
    const showStatusMarker = zoom >= 11
    const showStatusText = zoom >= 13

    // 제주도 해안선 레퍼런스 라인
    const coastline = L.polyline(jejuCoastCoords as [number, number][], {
      color: 'rgba(6, 182, 212, 0.18)',
      weight: 1.5,
      dashArray: '8, 6',
    })
    markersRef.current.addLayer(coastline)

    segments.forEach(seg => {
      const isSelected = selectedSeg.id === seg.id
      const color = esiColor(seg.esiNum)

      // 해안선 방향 계산 (세그먼트 폴리라인 각도 결정)
      const coastIdx = seg.id % (jejuCoastCoords.length - 1)
      const [clat1, clng1] = jejuCoastCoords[coastIdx]
      const [clat2, clng2] = jejuCoastCoords[(coastIdx + 1) % jejuCoastCoords.length]

      const dlat = clat2 - clat1
      const dlng = clng2 - clng1
      const dist = Math.sqrt(dlat * dlat + dlng * dlng)
      const nDlat = dist > 0 ? dlat / dist : 0
      const nDlng = dist > 0 ? dlng / dist : 1

      // 구간 길이를 위경도 단위로 변환 (줌 레벨에 따라 스케일링)
      const halfLen = Math.min(seg.lengthM / 200000, 0.012) * halfLenScale

      // 해안선 방향을 따라 폴리라인 좌표 생성
      const segCoords: [number, number][] = [
        [seg.lat - nDlat * halfLen, seg.lng - nDlng * halfLen],
        [seg.lat, seg.lng],
        [seg.lat + nDlat * halfLen, seg.lng + nDlng * halfLen],
      ]

      // 선택된 구간 글로우 효과
      if (isSelected) {
        const glow = L.polyline(segCoords, {
          color: '#22c55e',
          weight: glowWeight,
          opacity: 0.15,
          lineCap: 'round',
        })
        markersRef.current!.addLayer(glow)
      }

      // ESI 색상 구간 폴리라인
      const polyline = L.polyline(segCoords, {
        color: isSelected ? '#22c55e' : color,
        weight: isSelected ? selPolyWeight : polyWeight,
        opacity: isSelected ? 0.95 : 0.7,
        lineCap: 'round',
        lineJoin: 'round',
      })

      const statusIcon = seg.status === '완료' ? '✓' : seg.status === '진행중' ? '⏳' : '—'

      polyline.bindTooltip(
        `<div style="text-align:center;font-family:'Noto Sans KR',sans-serif;">
          <div style="font-weight:700;font-size:11px;">${seg.code} ${seg.area}</div>
          <div style="font-size:10px;opacity:0.7;">ESI ${seg.esi} · ${seg.length} · ${statusIcon} ${seg.status}</div>
        </div>`,
        {
          permanent: isSelected,
          direction: 'top',
          offset: [0, -10],
          className: 'scat-map-tooltip',
        }
      )

      polyline.on('click', () => {
        onSelectSeg(seg)
        onOpenPopup(seg.id % scatDetailData.length)
      })
      markersRef.current!.addLayer(polyline)

      // 조사 상태 마커 (DivIcon) — 줌 레벨에 따라 표시/크기 조절
      if (showStatusMarker) {
        const stColor = seg.status === '완료' ? '#22c55e' : seg.status === '진행중' ? '#eab308' : '#64748b'
        const stBg = seg.status === '완료' ? 'rgba(34,197,94,0.2)' : seg.status === '진행중' ? 'rgba(234,179,8,0.2)' : 'rgba(100,116,139,0.2)'
        const stText = seg.status === '완료' ? '✓' : seg.status === '진행중' ? '⏳' : '—'
        const half = Math.round(markerSize / 2)

        const statusMarker = L.marker([seg.lat, seg.lng], {
          icon: L.divIcon({
            className: '',
            html: `<div style="width:${markerSize}px;height:${markerSize}px;border-radius:50%;background:${stBg};border:${markerBorder}px solid ${stColor};display:flex;align-items:center;justify-content:center;font-size:${markerFontSize}px;color:${stColor};transform:translate(-${half}px,-${half}px);backdrop-filter:blur(4px);box-shadow:0 0 ${Math.round(markerSize / 3)}px ${stBg}">${showStatusText ? stText : ''}</div>`,
            iconSize: [0, 0],
          }),
        })

        statusMarker.on('click', () => {
          onSelectSeg(seg)
          onOpenPopup(seg.id % scatDetailData.length)
        })
        markersRef.current!.addLayer(statusMarker)
      }
    })
  }, [segments, selectedSeg, onSelectSeg, onOpenPopup, zoom])

  useEffect(() => {
    if (!mapRef.current) return
    mapRef.current.flyTo([selectedSeg.lat, selectedSeg.lng], 12, { duration: 0.6 })
  }, [selectedSeg])

  const doneCount = segments.filter(s => s.status === '완료').length
  const progCount = segments.filter(s => s.status === '진행중').length
  const totalLen = segments.reduce((a, s) => a + s.lengthM, 0)
  const doneLen = segments.filter(s => s.status === '완료').reduce((a, s) => a + s.lengthM, 0)
  const highSens = segments.filter(s => s.sensitivity === '최상' || s.sensitivity === '상').reduce((a, s) => a + s.lengthM, 0)
  const donePct = Math.round(doneCount / segments.length * 100)
  const progPct = Math.round(progCount / segments.length * 100)
  const notPct = 100 - donePct - progPct

  return (
    <div className="absolute inset-0 overflow-hidden">
      <style>{`
        .scat-map-tooltip {
          background: rgba(15,21,36,0.92) !important;
          border: 1px solid rgba(30,42,66,0.8) !important;
          color: #e4e8f1 !important;
          border-radius: 6px !important;
          padding: 4px 8px !important;
          box-shadow: 0 4px 12px rgba(0,0,0,0.4) !important;
        }
        .scat-map-tooltip::before {
          border-top-color: rgba(15,21,36,0.92) !important;
        }
      `}</style>
      <div ref={mapContainerRef} className="w-full h-full" />

      {/* Status chips */}
      <div className="absolute top-3.5 left-3.5 flex gap-2 z-[1000]">
        <div className="flex items-center gap-1.5 px-3 py-1.5 bg-[rgba(18,25,41,0.92)] backdrop-blur-xl border border-border rounded-full text-[11px] text-text-2 font-korean">
          <span className="w-1.5 h-1.5 rounded-full bg-status-green shadow-[0_0_6px_var(--green)]" />
          Pre-SCAT 사전조사
        </div>
        <div className="flex items-center gap-1.5 px-3 py-1.5 bg-[rgba(18,25,41,0.92)] backdrop-blur-xl border border-border rounded-full text-[11px] text-text-2 font-korean">
          제주도 — 해양경비안전서 관할 해안 · {segments.length}개 구간
        </div>
      </div>

      {/* Right info cards */}
      <div className="absolute top-3.5 right-3.5 w-[260px] flex flex-col gap-2 z-[1000] max-h-[calc(100%-100px)] overflow-y-auto scrollbar-thin">
        {/* ESI Legend */}
        <div className="bg-[rgba(18,25,41,0.92)] backdrop-blur-xl border border-border rounded-md p-3.5 shadow-[0_4px_20px_rgba(0,0,0,0.3)]">
          <div className="text-[10px] font-bold uppercase tracking-wider text-text-3 mb-2.5">ESI 민감도 분류 범례</div>
          {[
            { esi: 'ESI 10', label: '갯벌·습지·맹그로브', color: '#991b1b' },
            { esi: 'ESI 9', label: '쉘터 갯벌', color: '#b91c1c' },
            { esi: 'ESI 8', label: '쉘터 암반 해안', color: '#dc2626' },
            { esi: 'ESI 7', label: '노출 갯벌', color: '#ef4444' },
            { esi: 'ESI 6', label: '자갈·혼합 해안', color: '#f97316' },
            { esi: 'ESI 5', label: '혼합 모래/자갈', color: '#fb923c' },
            { esi: 'ESI 3-4', label: '모래 해안', color: '#facc15' },
            { esi: 'ESI 1-2', label: '암반·인공 구조물', color: '#4ade80' },
          ].map((item, i) => (
            <div key={i} className="flex items-center gap-2 py-1 text-[11px]">
              <span className="w-3.5 h-1.5 rounded-sm flex-shrink-0" style={{ background: item.color }} />
              <span className="text-text-2 font-korean">{item.label}</span>
              <span className="ml-auto font-mono text-[10px] text-text-1">{item.esi}</span>
            </div>
          ))}
        </div>

        {/* Progress */}
        <div className="bg-[rgba(18,25,41,0.92)] backdrop-blur-xl border border-border rounded-md p-3.5 shadow-[0_4px_20px_rgba(0,0,0,0.3)]">
          <div className="text-[10px] font-bold uppercase tracking-wider text-text-3 mb-2.5">조사 진행률</div>
          <div className="flex gap-0.5 h-3 rounded overflow-hidden mb-1">
            <div className="h-full transition-all duration-500" style={{ width: `${donePct}%`, background: 'var(--green)' }} />
            <div className="h-full transition-all duration-500" style={{ width: `${progPct}%`, background: 'var(--orange)' }} />
            <div className="h-full transition-all duration-500" style={{ width: `${notPct}%`, background: 'var(--bd)' }} />
          </div>
          <div className="flex justify-between mt-1">
            <span className="text-[9px] font-mono" style={{ color: 'var(--green)' }}>완료 {donePct}%</span>
            <span className="text-[9px] font-mono" style={{ color: 'var(--orange)' }}>진행 {progPct}%</span>
            <span className="text-[9px] font-mono text-text-3">미조사 {notPct}%</span>
          </div>
          <div className="mt-2.5">
            {[
              ['총 해안선', `${(totalLen / 1000).toFixed(1)} km`, ''],
              ['조사 완료', `${(doneLen / 1000).toFixed(1)} km`, 'var(--green)'],
              ['고민감 구간', `${(highSens / 1000).toFixed(1)} km`, 'var(--red)'],
              ['방제 우선 구간', `${segments.filter(s => s.sensitivity === '최상').length}개`, 'var(--orange)'],
            ].map(([label, val, color], i) => (
              <div key={i} className="flex justify-between py-1.5 border-b border-[rgba(30,42,74,0.3)] last:border-b-0 text-[11px]">
                <span className="text-text-2 font-korean">{label}</span>
                <span className="font-mono font-medium text-[11px]" style={{ color: color || undefined }}>{val}</span>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Coordinates */}
      <div className="absolute bottom-3 left-3 z-[1000] bg-[rgba(18,25,41,0.85)] backdrop-blur-xl border border-border rounded-sm px-3 py-1.5 font-mono text-[11px] text-text-2 flex gap-3.5">
        <span>위도 <span className="text-status-green font-medium">{selectedSeg.lat.toFixed(4)}°N</span></span>
        <span>경도 <span className="text-status-green font-medium">{selectedSeg.lng.toFixed(4)}°E</span></span>
        <span>축척 <span className="text-status-green font-medium">1:25,000</span></span>
      </div>
    </div>
  )
}

export default ScatMap
