import { useState, useCallback, useRef, useMemo } from 'react'
import { useI18n } from '../hooks/useI18n.ts'
import MapContainer from '../components/map/MapContainer.tsx'
import Sidebar from '../components/layout/Sidebar.tsx'
import RawDataPanel from '../components/RawDataPanel.tsx'
import type maplibregl from 'maplibre-gl'
import type { Layer } from '@deck.gl/core'
import {
  useRecentPositions,
  useRecentPositionsLayer,
  usePositionStore,
  VesselPopup,
  PositionFilterPanel,
} from '../features/recent-positions'
import {
  useVesselTracksLayer,
  TrackQueryPanel,
  TrackInfoPanel,
} from '../features/vessel-tracks'
import { useTrackStore } from '../features/vessel-tracks/stores/trackStore'
import {
  useReplayLayer,
  useReplayStore,
  useMergedTrackStore,
  ReplaySetupPanel,
  ReplayControlPanel,
} from '../features/viewport-replay'

type ApiMode = 'positions' | 'vessel' | 'replay'

/** 최근위치 — 선택된 선박의 원본 데이터 */
function usePositionRawData() {
  const selectedMmsi = usePositionStore((s) => s.selectedMmsi)
  const positions = usePositionStore((s) => s.positions)

  return useMemo(() => {
    if (!selectedMmsi) return null
    const vessel = positions.get(selectedMmsi)
    return vessel ?? null
  }, [selectedMmsi, positions])
}

/** 항적 — 조회 결과 요약 데이터 */
function useTrackRawData() {
  const tracks = useTrackStore((s) => s.tracks)

  return useMemo(() => {
    if (tracks.length === 0) return null
    return tracks.map((t) => ({
      vesselId: t.vesselId,
      shipName: t.shipName,
      shipKindCode: t.shipKindCode,
      nationalCode: t.nationalCode,
      pointCount: t.geometry.length,
      totalDistance: t.totalDistance,
      avgSpeed: t.avgSpeed,
      maxSpeed: t.maxSpeed,
      timeRange: t.timestampsMs.length >= 2
        ? [new Date(t.timestampsMs[0]).toISOString(), new Date(t.timestampsMs[t.timestampsMs.length - 1]).toISOString()]
        : null,
    }))
  }, [tracks])
}

/** 리플레이 — 청크 병합 결과 데이터 */
function useReplayRawData() {
  const vesselChunks = useMergedTrackStore((s) => s.vesselChunks)
  const queryCompleted = useReplayStore((s) => s.queryCompleted)
  const receivedChunks = useReplayStore((s) => s.receivedChunks)

  return useMemo(() => {
    if (vesselChunks.size === 0) return null
    const vessels: Record<string, unknown>[] = []
    for (const [mmsi, data] of vesselChunks) {
      vessels.push({
        vesselId: mmsi,
        shipName: data.shipName,
        shipKindCode: data.shipKindCode,
        nationalCode: data.nationalCode,
        chunkCount: data.chunks.length,
        totalPoints: data.chunks.reduce((sum, c) => sum + (c.geometry?.length ?? 0), 0),
      })
    }
    return {
      queryCompleted,
      receivedChunks,
      vesselCount: vessels.length,
      vessels,
    }
  }, [vesselChunks, queryCompleted, receivedChunks])
}

export default function ApiExplorer() {
  const { t } = useI18n()
  const [mode, setMode] = useState<ApiMode>('positions')
  const mapRef = useRef<maplibregl.Map | null>(null)
  const [zoom, setZoom] = useState(7)
  const [trackMmsi, setTrackMmsi] = useState<string | undefined>()
  const [replayLayers, setReplayLayers] = useState<Layer[]>([])

  const selectVessel = usePositionStore((s) => s.selectVessel)

  // 최근 위치 30초 폴링 (positions 모드일 때만)
  useRecentPositions(10, mode === 'positions')

  // Deck.gl 레이어 — positions
  const positionLayers = useRecentPositionsLayer({
    zoom,
    onVesselClick: (mmsi) => selectVessel(mmsi),
  })

  // Deck.gl 레이어 — vessel tracks
  const trackLayers = useVesselTracksLayer({ zoom })

  // Deck.gl 레이어 — replay (콜백으로 업데이트)
  const handleReplayLayersUpdate = useCallback((layers: Layer[]) => {
    setReplayLayers(layers)
  }, [])

  useReplayLayer({
    zoom,
    onLayersUpdate: handleReplayLayersUpdate,
  })

  const handleMapReady = useCallback((m: maplibregl.Map) => {
    mapRef.current = m
    setZoom(m.getZoom())
    m.on('zoom', () => setZoom(m.getZoom()))
  }, [])

  // 최근위치 → 항적조회 전환
  const handleTrackQuery = useCallback((mmsi: string) => {
    setTrackMmsi(mmsi)
    setMode('vessel')
    selectVessel(null)
  }, [selectVessel])

  // Raw Data 훅
  const positionData = usePositionRawData()
  const trackData = useTrackRawData()
  const replayData = useReplayRawData()

  // 모드별 Deck.gl 레이어
  const deckLayers: Layer[] =
    mode === 'positions' ? positionLayers :
    mode === 'vessel' ? trackLayers :
    mode === 'replay' ? replayLayers :
    []

  return (
    <div className="flex h-[calc(100vh-3.5rem)] overflow-hidden">
      {/* Sidebar */}
      <div className="relative flex">
        <Sidebar width={340}>
          <div className="space-y-4">
            <h2 className="text-lg font-bold">{t('explorer.title')}</h2>

            {/* 모드 선택 */}
            <div>
              <label className="mb-1 block text-xs font-medium text-muted">
                {t('explorer.apiType')}
              </label>
              <div className="space-y-1">
                {([
                  { value: 'positions' as const, label: t('explorer.recentPositions') },
                  { value: 'vessel' as const, label: t('explorer.vesselTracks') },
                  { value: 'replay' as const, label: '뷰포트 리플레이' },
                ] as const).map(opt => (
                  <button
                    key={opt.value}
                    onClick={() => setMode(opt.value)}
                    className={`w-full rounded-md px-3 py-2 text-left text-sm transition ${
                      mode === opt.value
                        ? 'bg-primary/10 font-medium text-primary'
                        : 'text-foreground hover:bg-surface-hover'
                    }`}
                  >
                    {opt.label}
                  </button>
                ))}
              </div>
            </div>

            {/* 모드별 사이드바 */}
            {mode === 'positions' && (
              <div className="rounded-lg border border-border p-3">
                <div className="mb-2 text-xs font-medium text-muted">선종 필터</div>
                <PositionFilterPanel />
              </div>
            )}

            {mode === 'vessel' && (
              <div className="rounded-lg border border-border p-3">
                <div className="mb-2 text-xs font-medium text-muted">항적 조회</div>
                <TrackQueryPanel initialMmsi={trackMmsi} />
              </div>
            )}

            {mode === 'replay' && (
              <div className="rounded-lg border border-border p-3">
                <div className="mb-2 text-xs font-medium text-muted">뷰포트 리플레이</div>
                <ReplaySetupPanel map={mapRef.current} />
              </div>
            )}

            {/* Response Data — Swagger Response 스타일 */}
            {mode === 'positions' && (
              <RawDataPanel
                title="선박 상세 (클릭)"
                data={positionData}
                emptyText="지도에서 선박을 클릭하세요"
              />
            )}
            {mode === 'vessel' && (
              <RawDataPanel
                title="항적 조회 결과"
                data={trackData}
                emptyText="MMSI를 입력하고 조회하세요"
              />
            )}
            {mode === 'replay' && (
              <RawDataPanel
                title="리플레이 데이터"
                data={replayData}
                emptyText="뷰포트 리플레이를 실행하세요"
              />
            )}
          </div>
        </Sidebar>
      </div>

      {/* Map area */}
      <div className="relative flex-1">
        <MapContainer onMapReady={handleMapReady} deckLayers={deckLayers} />

        {/* 모드 표시 */}
        <div className="absolute left-3 top-3 rounded-md bg-surface/90 px-3 py-1.5 text-xs font-medium shadow-sm backdrop-blur">
          {mode === 'positions' && t('explorer.recentPositions')}
          {mode === 'vessel' && t('explorer.vesselTracks')}
          {mode === 'replay' && '뷰포트 리플레이'}
        </div>

        {/* 모드별 오버레이 */}
        {mode === 'positions' && <VesselPopup onTrackQuery={handleTrackQuery} />}
        {mode === 'vessel' && <TrackInfoPanel />}
        {mode === 'replay' && <ReplayControlPanel />}
      </div>
    </div>
  )
}
