import { useEffect, useRef, useCallback } from 'react'
import maplibregl from 'maplibre-gl'
import { usePoller } from '../hooks/usePoller.ts'
import { useCachedState } from '../hooks/useCachedState.ts'
import { useI18n } from '../hooks/useI18n.ts'
import { monitorApi } from '../api/monitorApi.ts'
import { gisApi } from '../api/gisApi.ts'
import type { HaeguBoundary } from '../api/gisApi.ts'
import type { ThroughputMetrics, DataQuality, HaeguStat } from '../api/types.ts'
import MapContainer from '../components/map/MapContainer.tsx'
import MetricCard from '../components/charts/MetricCard.tsx'
import StatusBadge from '../components/common/StatusBadge.tsx'
import { formatNumber, formatDateTime } from '../utils/formatters.ts'

const POLL_INTERVAL = 30_000

/** 범례에 표시할 항목 */
const LEGEND_ITEMS = [
  { label: '1-9', color: 'rgba(59,130,246,0.45)' },
  { label: '10-49', color: 'rgba(16,185,129,0.6)' },
  { label: '50-99', color: 'rgba(245,158,11,0.7)' },
  { label: '100-199', color: 'rgba(239,68,68,0.7)' },
  { label: '200+', color: 'rgba(139,92,246,0.8)' },
]

export default function AreaStats() {
  const { t } = useI18n()
  const [haegu, setHaegu] = useCachedState<HaeguStat[]>('area.haegu', [])
  const [throughput, setThroughput] = useCachedState<ThroughputMetrics | null>('area.throughput', null)
  const [quality, setQuality] = useCachedState<DataQuality | null>('area.quality', null)
  const [boundaries, setBoundaries] = useCachedState<HaeguBoundary[]>('area.boundaries', [])

  const mapRef = useRef<maplibregl.Map | null>(null)
  const popupRef = useRef<maplibregl.Popup | null>(null)

  usePoller(() => {
    monitorApi.getHaeguRealtimeStats().then(setHaegu).catch(() => {})
    monitorApi.getThroughput().then(setThroughput).catch(() => {})
    monitorApi.getQuality().then(setQuality).catch(() => {})
  }, POLL_INTERVAL)

  // 경계 데이터는 1회만 로딩
  useEffect(() => {
    if (boundaries.length === 0) {
      gisApi.getHaeguBoundaries().then(setBoundaries).catch(() => {})
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  // GeoJSON 생성 함수
  const buildGeoJson = useCallback((): GeoJSON.FeatureCollection => {
    const statsMap = new Map<number, HaeguStat>()
    for (const h of haegu) {
      statsMap.set(h.haegu_no, h)
    }

    const features: GeoJSON.Feature[] = []
    for (const b of boundaries) {
      if (!b.geom_json) continue
      try {
        const geometry = JSON.parse(b.geom_json)
        const stat = statsMap.get(b.haegu_no)
        features.push({
          type: 'Feature',
          properties: {
            haegu_no: b.haegu_no,
            haegu_name: stat?.haegu_name ?? `대해구 ${b.haegu_no}`,
            vessels: stat?.current_vessels ?? 0,
            avg_speed: stat?.avg_speed ?? 0,
            avg_density: stat?.avg_density ?? 0,
          },
          geometry,
        })
      } catch {
        // skip invalid geom
      }
    }
    return { type: 'FeatureCollection', features }
  }, [boundaries, haegu])

  // 지도 레이어 업데이트
  useEffect(() => {
    const map = mapRef.current
    if (!map || boundaries.length === 0) return

    const geojson = buildGeoJson()

    if (map.getSource('haegu')) {
      (map.getSource('haegu') as maplibregl.GeoJSONSource).setData(geojson)
    } else {
      map.addSource('haegu', { type: 'geojson', data: geojson })

      // fill 색상 step expression
      // ['step', input, default, stop1, output1, stop2, output2, ...]
      const fillColor = [
        'step',
        ['get', 'vessels'],
        'rgba(59,130,246,0.05)',  // default (vessels < 0)
        0, 'rgba(59,130,246,0.25)',   // 0
        1, 'rgba(59,130,246,0.45)',   // 1-9
        10, 'rgba(16,185,129,0.55)',  // 10-49
        50, 'rgba(245,158,11,0.6)',   // 50-99
        100, 'rgba(239,68,68,0.6)',   // 100-199
        200, 'rgba(139,92,246,0.7)',  // 200+
      ] as unknown as maplibregl.ExpressionSpecification

      map.addLayer({
        id: 'haegu-fill',
        type: 'fill',
        source: 'haegu',
        paint: {
          'fill-color': fillColor,
          'fill-opacity': 0.8,
        },
      })

      map.addLayer({
        id: 'haegu-line',
        type: 'line',
        source: 'haegu',
        paint: {
          'line-color': 'rgba(100,116,139,0.5)',
          'line-width': 1,
        },
      })

      // hover popup
      const popup = new maplibregl.Popup({
        closeButton: false,
        closeOnClick: false,
        maxWidth: '220px',
      })
      popupRef.current = popup

      map.on('mousemove', 'haegu-fill', (e) => {
        if (!e.features || e.features.length === 0) return
        map.getCanvas().style.cursor = 'pointer'
        const props = e.features[0].properties
        if (!props) return

        popup
          .setLngLat(e.lngLat)
          .setHTML(
            `<div style="font-size:13px;line-height:1.5">
              <strong>${props.haegu_name}</strong><br/>
              ${t('area.currentVessels')}: <b>${props.vessels}</b>${t('area.vessels')}<br/>
              ${t('area.avgSpeed')}: ${Number(props.avg_speed).toFixed(1)} kn
            </div>`,
          )
          .addTo(map)
      })

      map.on('mouseleave', 'haegu-fill', () => {
        map.getCanvas().style.cursor = ''
        popup.remove()
      })
    }
  }, [boundaries, haegu, buildGeoJson, t])

  const handleMapReady = useCallback((map: maplibregl.Map) => {
    mapRef.current = map
  }, [])

  // cleanup popup on unmount
  useEffect(() => {
    return () => {
      popupRef.current?.remove()
    }
  }, [])

  return (
    <div className="space-y-6 fade-in">
      <h1 className="text-2xl font-bold">{t('area.title')}</h1>

      {/* Summary Cards */}
      <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
        <MetricCard
          title={t('area.activeHaegu')}
          value={haegu.length}
          subtitle={t('area.activeHaeguDesc')}
        />
        <MetricCard
          title={t('area.totalVessels')}
          value={formatNumber(haegu.reduce((sum, h) => sum + (h.current_vessels ?? 0), 0))}
        />
        <MetricCard
          title={t('area.dataQuality')}
          value={quality?.qualityScore ?? '-'}
          trend={quality?.qualityScore === 'GOOD' ? 'up' : quality?.qualityScore === 'NEEDS_ATTENTION' ? 'down' : 'neutral'}
        />
        <MetricCard
          title={t('area.avgDensity')}
          value={haegu.length > 0
            ? (haegu.reduce((sum, h) => sum + (h.avg_density ?? 0), 0) / haegu.length).toFixed(2)
            : '-'}
        />
      </div>

      {/* Haegu Map (choropleth) */}
      <div className="sb-card">
        <div className="sb-card-header">{t('area.haeguMap')}</div>
        <div className="relative" style={{ height: 480 }}>
          <MapContainer onMapReady={handleMapReady} />
          {/* Legend */}
          <div className="absolute bottom-4 left-4 rounded-lg bg-surface/90 px-3 py-2 shadow-lg backdrop-blur-sm">
            <div className="mb-1.5 text-xs font-medium text-muted">{t('area.mapLegend')}</div>
            <div className="space-y-1">
              {LEGEND_ITEMS.map((item) => (
                <div key={item.label} className="flex items-center gap-2 text-xs">
                  <span
                    className="inline-block h-3 w-5 rounded"
                    style={{ backgroundColor: item.color }}
                  />
                  <span>{item.label}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>

      {/* Haegu Stats Table */}
      <div className="sb-card">
        <div className="sb-card-header">{t('area.haeguStats')}</div>
        {haegu.length === 0 ? (
          <div className="py-8 text-center text-sm text-muted">{t('common.noData')}</div>
        ) : (
          <div className="sb-table-wrapper">
            <table className="sb-table">
              <thead>
                <tr>
                  <th>{t('area.haeguNo')}</th>
                  <th>{t('area.haeguName')}</th>
                  <th className="text-right">{t('area.currentVessels')}</th>
                  <th className="text-right">{t('area.avgSpeed')}</th>
                  <th className="text-right">{t('area.avgDensityCol')}</th>
                  <th>{t('area.lastUpdate')}</th>
                </tr>
              </thead>
              <tbody>
                {haegu.map(h => (
                  <tr key={h.haegu_no}>
                    <td className="font-mono">{h.haegu_no}</td>
                    <td>{h.haegu_name}</td>
                    <td className="text-right font-bold">{formatNumber(h.current_vessels)}</td>
                    <td className="text-right">{(h.avg_speed ?? 0).toFixed(1)} kn</td>
                    <td className="text-right">{(h.avg_density ?? 0).toFixed(4)}</td>
                    <td className="text-xs text-muted">{formatDateTime(h.last_update)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>

      {/* Throughput + Quality */}
      <div className="grid gap-4 lg:grid-cols-2">
        {/* Throughput */}
        <div className="sb-card">
          <div className="sb-card-header">{t('area.throughput')}</div>
          {throughput ? (
            <div className="space-y-3">
              {throughput.avgVesselsPerMinute != null && (
                <div className="grid grid-cols-2 gap-3 text-center text-sm">
                  <div>
                    <div className="text-lg font-bold">{Math.round(throughput.avgVesselsPerMinute)}</div>
                    <div className="text-xs text-muted">{t('area.vesselsPerMin')}</div>
                  </div>
                  <div>
                    <div className="text-lg font-bold">{formatNumber(Math.round(throughput.avgVesselsPerHour ?? 0))}</div>
                    <div className="text-xs text-muted">{t('area.vesselsPerHour')}</div>
                  </div>
                </div>
              )}
              {throughput.partitionSizes && throughput.partitionSizes.length > 0 && (
                <div>
                  <div className="mb-2 text-xs font-medium text-muted">{t('area.tableSizes')}</div>
                  <div className="space-y-1">
                    {throughput.partitionSizes.map((p, i) => (
                      <div key={i} className="flex items-center justify-between rounded bg-surface-hover px-3 py-1.5 text-sm">
                        <span className="font-mono text-xs">{p.tablename}</span>
                        <span className="font-medium">{p.size}</span>
                      </div>
                    ))}
                  </div>
                </div>
              )}
              {(!throughput.avgVesselsPerMinute && (!throughput.partitionSizes || throughput.partitionSizes.length === 0)) && (
                <div className="py-4 text-center text-sm text-muted">{t('common.noData')}</div>
              )}
            </div>
          ) : (
            <div className="py-4 text-center text-sm text-muted">{t('common.loading')}</div>
          )}
        </div>

        {/* Data Quality */}
        <div className="sb-card">
          <div className="sb-card-header">{t('area.dataQualityTitle')}</div>
          {quality ? (
            <div className="space-y-3">
              <div className="flex items-baseline gap-2">
                <StatusBadge status={quality.qualityScore === 'GOOD' ? 'COMPLETED' : quality.qualityScore === 'ERROR' ? 'FAILED' : 'STOPPED'} />
                <span className="text-lg font-bold">{quality.qualityScore}</span>
              </div>
              <div className="grid grid-cols-2 gap-3 text-sm">
                <div className="rounded-lg bg-surface-hover p-3">
                  <div className="text-xs text-muted">{t('area.duplicates')}</div>
                  <div className="text-lg font-bold">{formatNumber(quality.duplicateRecords)}</div>
                </div>
                <div className="rounded-lg bg-surface-hover p-3">
                  <div className="text-xs text-muted">{t('area.stalePositions')}</div>
                  <div className="text-lg font-bold">{formatNumber(quality.stalePositions)}</div>
                </div>
              </div>
              <div className="text-xs text-muted">
                {t('area.checkedAt')}: {formatDateTime(quality.checkedAt)}
              </div>
            </div>
          ) : (
            <div className="py-4 text-center text-sm text-muted">{t('common.loading')}</div>
          )}
        </div>
      </div>
    </div>
  )
}
