import { useState, useMemo, useCallback } from 'react'
import { Map, Marker, useControl } from '@vis.gl/react-maplibre'
import { MapboxOverlay } from '@deck.gl/mapbox'
import type { Layer } from '@deck.gl/core'
import type { StyleSpecification, MapLayerMouseEvent } from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css'
import { WeatherRightPanel } from './WeatherRightPanel'
import { WeatherMapOverlay, useWeatherDeckLayers } from './WeatherMapOverlay'
// import { OceanForecastOverlay } from './OceanForecastOverlay'
// import { useOceanCurrentLayers } from './OceanCurrentLayer'
import { useWaterTemperatureLayers } from './WaterTemperatureLayer'
import { WindParticleLayer } from './WindParticleLayer'
import { OceanCurrentParticleLayer } from './OceanCurrentParticleLayer'
import { useWeatherData } from '../hooks/useWeatherData'
// import { useOceanForecast } from '../hooks/useOceanForecast'
import { WeatherMapControls } from './WeatherMapControls'

type TimeOffset = '0' | '3' | '6' | '9'

interface WeatherStation {
  id: string
  name: string
  location: { lat: number; lon: number }
  wind: {
    speed: number
    direction: number
    speed_1k: number
    speed_3k: number
  }
  wave: {
    height: number
    period: number
  }
  temperature: {
    current: number
    feelsLike: number
  }
  pressure: number
  visibility: number
  salinity?: number
}

const CARDINAL_LABELS = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'] as const

function degreesToCardinal(deg: number): string {
  const idx = Math.round(((deg % 360) + 360) % 360 / 22.5) % 16
  return CARDINAL_LABELS[idx]
}

interface WeatherForecast {
  time: string
  hour: string
  icon: string
  temperature: number
  windSpeed: number
}

// Base weather station locations
const BASE_STATIONS = [
  { id: 'incheon', name: '인천', location: { lat: 37.45, lon: 126.43 } },
  { id: 'ulsan', name: '울산', location: { lat: 35.52, lon: 129.38 } },
  { id: 'yeosu', name: '여수', location: { lat: 34.74, lon: 127.75 } },
  { id: 'jeju', name: '제주', location: { lat: 33.51, lon: 126.53 } },
  { id: 'pohang', name: '포항', location: { lat: 36.03, lon: 129.38 } },
  { id: 'mokpo', name: '목포', location: { lat: 34.78, lon: 126.38 } },
  { id: 'gunsan', name: '군산', location: { lat: 35.97, lon: 126.7 } },
  { id: 'sokcho', name: '속초', location: { lat: 38.21, lon: 128.59 } },
  { id: 'tongyeong', name: '통영', location: { lat: 34.83, lon: 128.43 } },
  { id: 'donghae', name: '동해', location: { lat: 37.52, lon: 129.14 } },
]

// Generate forecast data based on time offset
const generateForecast = (timeOffset: TimeOffset): WeatherForecast[] => {
  const baseHour = parseInt(timeOffset)
  const forecasts: WeatherForecast[] = []
  const icons = ['☀️', '⛅', '☁️', '🌦️', '🌧️']

  for (let i = 0; i < 5; i++) {
    const hour = baseHour + i * 3
    forecasts.push({
      time: `+${hour}시`,
      hour: `${hour}시`,
      icon: icons[i % icons.length],
      temperature: Math.floor(Math.random() * 5) + 5,
      windSpeed: Math.floor(Math.random() * 5) + 6,
    })
  }
  return forecasts
}

// CartoDB Dark Matter 스타일 (기존 WeatherView와 동일)
const WEATHER_MAP_STYLE: StyleSpecification = {
  version: 8,
  sources: {
    'carto-dark': {
      type: 'raster',
      tiles: [
        'https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
        'https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
        'https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
      ],
      tileSize: 256,
      attribution:
        '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> &copy; <a href="https://carto.com/attributions">CARTO</a>',
    },
  },
  layers: [
    {
      id: 'carto-dark-layer',
      type: 'raster',
      source: 'carto-dark',
      minzoom: 0,
      maxzoom: 22,
    },
  ],
}

// 한국 해역 중심 좌표 (한반도 중앙)
const WEATHER_MAP_CENTER: [number, number] = [127.8, 36.5] // [lng, lat]
const WEATHER_MAP_ZOOM = 7

// deck.gl 오버레이 컴포넌트 (MapLibre 컨트롤로 등록)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function DeckGLOverlay({ layers }: { layers: Layer[] }) {
  const overlay = useControl<MapboxOverlay>(() => new MapboxOverlay({ interleaved: true }))
  overlay.setProps({ layers })
  return null
}

/**
 * WeatherMapInner — Map 컴포넌트 내부 (useMap / useControl 사용 가능 영역)
 */
interface WeatherMapInnerProps {
  weatherStations: WeatherStation[]
  enabledLayers: Set<string>
  selectedStationId: string | null
  onStationClick: (station: WeatherStation) => void
  mapCenter: [number, number]
  mapZoom: number
  clickedLocation: { lat: number; lon: number } | null
}

function WeatherMapInner({
  weatherStations,
  enabledLayers,
  selectedStationId,
  onStationClick,
  mapCenter,
  mapZoom,
  clickedLocation,
}: WeatherMapInnerProps) {
  // deck.gl layers 조합
  const weatherDeckLayers = useWeatherDeckLayers(
    weatherStations,
    enabledLayers,
    selectedStationId,
    onStationClick
  )
  // const oceanCurrentLayers = useOceanCurrentLayers({
  //   visible: enabledLayers.has('oceanCurrent'),
  //   opacity: 0.7,
  // })
  const waterTempLayers = useWaterTemperatureLayers({
    visible: enabledLayers.has('waterTemperature'),
    opacity: 0.5,
  })

  const deckLayers = useMemo(
    () => [...waterTempLayers, ...weatherDeckLayers],
    [waterTempLayers, weatherDeckLayers]
  )

  return (
    <>
      {/* deck.gl 오버레이 */}
      <DeckGLOverlay layers={deckLayers} />

      {/* 해황예보도 — 임시 비활성화
      <OceanForecastOverlay
        forecast={selectedForecast}
        opacity={oceanForecastOpacity}
        visible={enabledLayers.has('oceanForecast')}
      /> */}

      {/* 해류 흐름 파티클 애니메이션 (Canvas 직접 조작) */}
      <OceanCurrentParticleLayer
        visible={enabledLayers.has('oceanCurrentParticle')}
      />

      {/* 기상 관측소 HTML 오버레이 (풍향 화살표 + 라벨) */}
      <WeatherMapOverlay
        stations={weatherStations}
        enabledLayers={enabledLayers}
        onStationClick={onStationClick}
        selectedStationId={selectedStationId}
      />

      {/* 바람 파티클 애니메이션 (Canvas 직접 조작) */}
      <WindParticleLayer
        visible={enabledLayers.has('windParticle')}
        stations={weatherStations}
      />

      {/* 클릭 위치 마커 */}
      {clickedLocation && (
        <Marker
          longitude={clickedLocation.lon}
          latitude={clickedLocation.lat}
          anchor="bottom"
        >
          <div className="flex flex-col items-center pointer-events-none">
            {/* 펄스 링 */}
            <div className="relative flex items-center justify-center">
              <div className="absolute w-8 h-8 rounded-full border-2 border-primary-cyan animate-ping opacity-60" />
              <div className="w-4 h-4 rounded-full bg-primary-cyan border-2 border-white shadow-lg" />
            </div>
            {/* 핀 꼬리 */}
            <div className="w-px h-3 bg-primary-cyan" />
            {/* 좌표 라벨 */}
            <div className="px-2 py-1 bg-bg-0/90 border border-primary-cyan rounded text-[10px] text-primary-cyan whitespace-nowrap backdrop-blur-sm">
              {clickedLocation.lat.toFixed(3)}°N&nbsp;{clickedLocation.lon.toFixed(3)}°E
            </div>
          </div>
        </Marker>
      )}

      {/* 줌 컨트롤 */}
      <WeatherMapControls center={mapCenter} zoom={mapZoom} />
    </>
  )
}

export function WeatherView() {
  const { weatherStations, loading, error, lastUpdate } = useWeatherData(BASE_STATIONS)


  // const {
  //   selectedForecast,
  //   availableTimes,
  //   loading: oceanLoading,
  //   error: oceanError,
  //   selectForecast,
  // } = useOceanForecast('KOREA')

  const [timeOffset, setTimeOffset] = useState<TimeOffset>('0')
  const [selectedStationRaw, setSelectedStation] = useState<WeatherStation | null>(null)
  const [selectedLocation, setSelectedLocation] = useState<{ lat: number; lon: number } | null>(
    null
  )
  const [enabledLayers, setEnabledLayers] = useState<Set<string>>(new Set(['wind']))
  // const [oceanForecastOpacity, setOceanForecastOpacity] = useState(0.6)

  // 첫 관측소 자동 선택 (파생 값)
  const selectedStation = selectedStationRaw ?? weatherStations[0] ?? null

  const handleStationClick = useCallback(
    (station: WeatherStation) => {
      setSelectedStation(station)
      setSelectedLocation(null)
    },
    []
  )

  const handleMapClick = useCallback(
    (e: MapLayerMouseEvent) => {
      const { lat, lng } = e.lngLat
      if (weatherStations.length === 0) return

      // 가장 가까운 관측소 선택
      const nearestStation = weatherStations.reduce((nearest, station) => {
        const distance = Math.sqrt(
          Math.pow(station.location.lat - lat, 2) + Math.pow(station.location.lon - lng, 2)
        )
        const nearestDistance = Math.sqrt(
          Math.pow(nearest.location.lat - lat, 2) + Math.pow(nearest.location.lon - lng, 2)
        )
        return distance < nearestDistance ? station : nearest
      }, weatherStations[0])

      setSelectedStation(nearestStation)
      setSelectedLocation({ lat, lon: lng })
    },
    [weatherStations]
  )

  const toggleLayer = useCallback((layer: string) => {
    setEnabledLayers((prev) => {
      const next = new Set(prev)
      if (next.has(layer)) {
        next.delete(layer)
      } else {
        next.add(layer)
      }
      return next
    })
  }, [])

  const weatherData = selectedStation
    ? {
        stationName: selectedLocation
          ? `해양 지점 (${selectedLocation.lat.toFixed(2)}°N, ${selectedLocation.lon.toFixed(2)}°E)`
          : selectedStation.name,
        location: selectedLocation || selectedStation.location,
        currentTime: new Date().toLocaleTimeString('ko-KR', {
          hour: '2-digit',
          minute: '2-digit',
        }),
        wind: {
          ...selectedStation.wind,
          directionLabel: degreesToCardinal(selectedStation.wind.direction),
        },
        wave: {
          ...selectedStation.wave,
          maxHeight: Number((selectedStation.wave.height * 1.6).toFixed(1)),
          direction: degreesToCardinal(selectedStation.wind.direction + 45),
        },
        temperature: selectedStation.temperature,
        pressure: selectedStation.pressure,
        visibility: selectedStation.visibility,
        salinity: selectedStation.salinity ?? 31.2,
        astronomy: {
          sunrise: '07:12',
          sunset: '17:58',
          moonrise: '19:35',
          moonset: '01:50',
          moonPhase: '상현달 14일',
          tidalRange: 6.7,
        },
        alert: '풍랑주의보 예상 08:00~',
        forecast: generateForecast(timeOffset),
      }
    : null

  return (
    <div className="flex flex-1 overflow-hidden">
      {/* Main Map Area */}
      <div className="flex-1 relative flex flex-col overflow-hidden">
        {/* Tab Navigation */}
        <div className="flex items-center border-b border-border bg-bg-1 shrink-0">
          <div className="flex items-center gap-2 px-6">
            {(['0', '3', '6', '9'] as TimeOffset[]).map((offset) => (
              <button
                key={offset}
                onClick={() => setTimeOffset(offset)}
                className={`px-3 py-2 text-xs font-semibold rounded transition-all ${
                  timeOffset === offset
                    ? 'bg-primary-cyan text-bg-0'
                    : 'bg-bg-3 border border-border text-text-2 hover:bg-bg-hover'
                }`}
              >
                {offset === '0' ? '현재' : `+${offset}시간`}
              </button>
            ))}

            <div className="flex items-center gap-2 ml-4">
              <span className="text-xs text-text-3">
                {lastUpdate
                  ? `마지막 업데이트: ${lastUpdate.toLocaleTimeString('ko-KR', {
                      hour: '2-digit',
                      minute: '2-digit',
                    })}`
                  : '데이터 로딩 중...'}
              </span>
              {loading && (
                <div className="w-4 h-4 border-2 border-primary-cyan border-t-transparent rounded-full animate-spin" />
              )}
              {error && <span className="text-xs text-status-red">⚠️ {error}</span>}
            </div>
          </div>

          <div className="flex-1" />
        </div>

        {/* Map */}
        <div className="flex-1 relative">
          <Map
            initialViewState={{
              longitude: WEATHER_MAP_CENTER[0],
              latitude: WEATHER_MAP_CENTER[1],
              zoom: WEATHER_MAP_ZOOM,
            }}
            mapStyle={WEATHER_MAP_STYLE}
            className="w-full h-full"
            onClick={handleMapClick}
            attributionControl={false}
          >
            <WeatherMapInner
              weatherStations={weatherStations}
              enabledLayers={enabledLayers}
              selectedStationId={selectedStation?.id || null}
              onStationClick={handleStationClick}
              mapCenter={WEATHER_MAP_CENTER}
              mapZoom={WEATHER_MAP_ZOOM}
              clickedLocation={selectedLocation}
            />
          </Map>

          {/* 레이어 컨트롤 */}
          <div className="absolute top-4 left-4 bg-bg-1/85 border border-border rounded-md backdrop-blur-sm z-10" style={{ padding: '6px 10px' }}>
            <div className="text-[9px] font-semibold text-text-1 mb-1.5 font-korean">기상 레이어</div>
            <div className="flex flex-col gap-1">
              <label className="flex items-center gap-1.5 cursor-pointer">
                <input
                  type="checkbox"
                  checked={enabledLayers.has('windParticle')}
                  onChange={() => toggleLayer('windParticle')}
                  className="w-3 h-3 rounded border-border bg-bg-2 text-primary-cyan accent-[var(--cyan)]"
                />
                <span className="text-[9px] text-text-2">🌬️ 바람 흐름</span>
              </label>
              <label className="flex items-center gap-1.5 cursor-pointer">
                <input
                  type="checkbox"
                  checked={enabledLayers.has('wind')}
                  onChange={() => toggleLayer('wind')}
                  className="w-3 h-3 rounded border-border bg-bg-2 text-primary-cyan accent-[var(--cyan)]"
                />
                <span className="text-[9px] text-text-2">🌬️ 바람 벡터</span>
              </label>
              <label className="flex items-center gap-1.5 cursor-pointer">
                <input
                  type="checkbox"
                  checked={enabledLayers.has('waves')}
                  onChange={() => toggleLayer('waves')}
                  className="w-3 h-3 rounded border-border bg-bg-2 text-primary-cyan accent-[var(--cyan)]"
                />
                <span className="text-[9px] text-text-2">🌊 파고 분포</span>
              </label>
              <label className="flex items-center gap-1.5 cursor-pointer">
                <input
                  type="checkbox"
                  checked={enabledLayers.has('temperature')}
                  onChange={() => toggleLayer('temperature')}
                  className="w-3 h-3 rounded border-border bg-bg-2 text-primary-cyan accent-[var(--cyan)]"
                />
                <span className="text-[9px] text-text-2">🌡️ 수온 분포</span>
              </label>
              <label className="flex items-center gap-1.5 cursor-pointer">
                <input
                  type="checkbox"
                  checked={enabledLayers.has('oceanCurrentParticle')}
                  onChange={() => toggleLayer('oceanCurrentParticle')}
                  className="w-3 h-3 rounded border-border bg-bg-2 text-primary-cyan accent-[var(--cyan)]"
                />
                <span className="text-[9px] text-text-2">🌊 해류 흐름</span>
              </label>
              <label className="flex items-center gap-1.5 cursor-pointer">
                <input
                  type="checkbox"
                  checked={enabledLayers.has('waterTemperature')}
                  onChange={() => toggleLayer('waterTemperature')}
                  className="w-3 h-3 rounded border-border bg-bg-2 text-primary-cyan accent-[var(--cyan)]"
                />
                <span className="text-[9px] text-text-2">🌡️ 수온 색상도</span>
              </label>
            </div>
          </div>

          {/* 범례 */}
          <div className="absolute bottom-4 left-4 bg-bg-1/85 border border-border rounded-md backdrop-blur-sm z-10" style={{ padding: '6px 10px', maxWidth: 180 }}>
            <div className="text-[9px] font-semibold text-text-1 mb-1.5 font-korean">기상 범례</div>
            <div className="flex flex-col gap-1.5" style={{ fontSize: 8 }}>
              {/* 바람 */}
              <div>
                <div className="font-semibold text-text-2 mb-0.5" style={{ fontSize: 8 }}>바람 (m/s)</div>
                <div className="flex items-center gap-px h-[6px] rounded-sm overflow-hidden mb-0.5">
                  <div className="flex-1 h-full" style={{ background: '#6271b7' }} />
                  <div className="flex-1 h-full" style={{ background: '#39a0f6' }} />
                  <div className="flex-1 h-full" style={{ background: '#50d591' }} />
                  <div className="flex-1 h-full" style={{ background: '#a5e23f' }} />
                  <div className="flex-1 h-full" style={{ background: '#fae21e' }} />
                  <div className="flex-1 h-full" style={{ background: '#faaa19' }} />
                  <div className="flex-1 h-full" style={{ background: '#f05421' }} />
                  <div className="flex-1 h-full" style={{ background: '#b41e46' }} />
                </div>
                <div className="flex justify-between text-text-3" style={{ fontSize: 7 }}>
                  <span>3</span><span>5</span><span>7</span><span>10</span><span>13</span><span>16</span><span>20+</span>
                </div>
              </div>
              {/* 해류 */}
              <div className="pt-1 border-t border-border">
                <div className="font-semibold text-text-2 mb-0.5" style={{ fontSize: 8 }}>해류 (m/s)</div>
                <div className="flex items-center gap-px h-[6px] rounded-sm overflow-hidden mb-0.5">
                  <div className="flex-1 h-full" style={{ background: 'rgb(59, 130, 246)' }} />
                  <div className="flex-1 h-full" style={{ background: 'rgb(6, 182, 212)' }} />
                  <div className="flex-1 h-full" style={{ background: 'rgb(34, 197, 94)' }} />
                  <div className="flex-1 h-full" style={{ background: 'rgb(249, 115, 22)' }} />
                </div>
                <div className="flex justify-between text-text-3" style={{ fontSize: 7 }}>
                  <span>0.2</span><span>0.4</span><span>0.6</span><span>0.6+</span>
                </div>
              </div>
              {/* 파고 */}
              <div className="pt-1 border-t border-border">
                <div className="font-semibold text-text-2 mb-0.5" style={{ fontSize: 8 }}>파고 (m)</div>
                <div className="flex items-center gap-1">
                  <div className="w-2 h-2 rounded-full bg-blue-500" />
                  <span className="text-text-3">&lt;1.5 낮음</span>
                  <div className="w-2 h-2 rounded-full bg-orange-500 ml-1" />
                  <span className="text-text-3">~2.5</span>
                  <div className="w-2 h-2 rounded-full bg-red-500 ml-1" />
                  <span className="text-text-3">&gt;2.5</span>
                </div>
              </div>
            </div>
            <div className="mt-1 pt-1 border-t border-border text-text-3 font-korean" style={{ fontSize: 7 }}>
              💡 지도 클릭 → 기상 예보 확인
            </div>
          </div>
        </div>
      </div>

      {/* Right Panel */}
      <WeatherRightPanel weatherData={weatherData} />
    </div>
  )
}
