import { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import maplibregl from 'maplibre-gl';
import { BaseMap, createStaticLayers, createMarkerLayer, createRadiusLayer, useMapLayers, type MapHandle } from '@lib/map';
import type { MarkerData } from '@lib/map';
import { Card, CardContent } from '@shared/components/ui/card';
import { Badge } from '@shared/components/ui/badge';
import { PageContainer } from '@shared/components/layout';
import { AlertTriangle, Ship, Radio, Zap, Activity, Clock, Pin, Loader2, WifiOff } from 'lucide-react';
import {
  fetchVesselAnalysis,
  type VesselAnalysisItem,
} from '@/services/vesselAnalysisApi';
import {
  getEvents,
  type PredictionEvent,
} from '@/services/event';

import { getAlertLevelHex } from '@shared/constants/alertLevels';

interface MapEvent {
  id: string;
  type: string;
  mmsi: string;
  nationality: string;
  time: string;
  vesselName: string;
  risk: number;
  lat: number;
  lng: number;
  level: string;
}

const EVENT_COLORS: Record<string, string> = {
  'EEZ 침범': '#ef4444',
  '다크베셀': '#f97316',
  'AIS 신호 소실': '#eab308',
};

const eventIconMap: Record<string, typeof AlertTriangle> = {
  'EEZ 침범': AlertTriangle,
  '다크베셀': Ship,
  'AIS 신호 소실': Radio,
};

const MAX_VESSEL_MARKERS = 100;

function RiskBar({ value, size = 'md' }: { value: number; size?: 'sm' | 'md' }) {
  const pct = value * 100;
  const h = size === 'sm' ? 'h-1' : 'h-1.5';
  return (
    <div className="flex items-center gap-2">
      <div className={`flex-1 ${h} bg-secondary rounded-full overflow-hidden`}>
        <div className={`${h} bg-red-500 rounded-full`} style={{ width: `${pct}%` }} />
      </div>
      <span className="text-xs font-medium text-red-400">{value.toFixed(2)}</span>
    </div>
  );
}

export function LiveMapView() {
  // 실데이터 상태
  const [vesselItems, setVesselItems] = useState<VesselAnalysisItem[]>([]);
  const [activeEvents, setActiveEvents] = useState<PredictionEvent[]>([]);
  const [serviceAvailable, setServiceAvailable] = useState(true);
  const [loading, setLoading] = useState(true);

  // 데이터 로드
  useEffect(() => {
    let cancelled = false;

    const loadData = async () => {
      setLoading(true);
      try {
        const [analysisRes, eventsRes] = await Promise.all([
          fetchVesselAnalysis().catch(() => null),
          getEvents({ status: 'NEW,ACK,IN_PROGRESS', size: 10 }).catch(() => null),
        ]);

        if (cancelled) return;

        if (analysisRes) {
          setServiceAvailable(analysisRes.serviceAvailable);
          // riskScore 내림차순 정렬, 최대 100건
          const sorted = [...analysisRes.items].sort(
            (a, b) => b.algorithms.riskScore.score - a.algorithms.riskScore.score,
          );
          setVesselItems(sorted.slice(0, MAX_VESSEL_MARKERS));
        } else {
          setServiceAvailable(false);
        }

        setActiveEvents(eventsRes?.content ?? []);
      } catch {
        setServiceAvailable(false);
      } finally {
        if (!cancelled) setLoading(false);
      }
    };

    loadData();
    return () => { cancelled = true; };
  }, []);

  // 이벤트 → MapEvent 변환
  const mapEvents: MapEvent[] = useMemo(
    () =>
      activeEvents
        .filter((e) => e.lat != null && e.lon != null)
        .map((e) => ({
          id: String(e.id),
          type: e.category,
          mmsi: e.vesselMmsi ?? '미상',
          nationality: e.vesselMmsi?.startsWith('412') ? 'CN' : e.vesselMmsi?.startsWith('440') ? 'KR' : '미상',
          time: e.occurredAt.includes(' ') ? e.occurredAt.split(' ')[1]?.slice(0, 5) ?? e.occurredAt : e.occurredAt,
          vesselName: e.vesselName ?? '미상',
          risk: e.aiConfidence ?? (e.level === 'CRITICAL' ? 0.94 : e.level === 'HIGH' ? 0.91 : 0.88),
          lat: e.lat!,
          lng: e.lon!,
          level: e.level,
        })),
    [activeEvents],
  );

  // 선박 분석 데이터 → 마커용 변환 (좌표 없으므로 zone 기반 더미 좌표 생성)
  // vessel_analysis에는 좌표가 없으므로 zone 기반 대략적 배치
  const vesselMarkers = useMemo(() => {
    // zone → 대략적 좌표 매핑
    const ZONE_COORDS: Record<string, { lat: number; lng: number }> = {
      WEST_SEA: { lat: 36.5, lng: 124.5 },
      SOUTH_SEA: { lat: 33.5, lng: 127.0 },
      EAST_SEA: { lat: 37.0, lng: 130.0 },
      JEJU: { lat: 33.2, lng: 126.5 },
      NLL: { lat: 37.8, lng: 125.0 },
    };
    const DEFAULT_COORD = { lat: 35.5, lng: 126.5 };

    return vesselItems.map((item, idx) => {
      const zone = item.algorithms.location.zone;
      const base = ZONE_COORDS[zone] ?? DEFAULT_COORD;
      // 같은 zone 내에서 약간의 오프셋 추가
      const offset = idx * 0.03;
      return {
        item,
        lat: base.lat + (Math.sin(idx * 2.1) * 0.8) + offset * 0.1,
        lng: base.lng + (Math.cos(idx * 1.7) * 1.2) + offset * 0.1,
      };
    });
  }, [vesselItems]);

  const [selectedEvent, setSelectedEvent] = useState<MapEvent | null>(null);
  const mapRef = useRef<MapHandle>(null);
  const mapInstanceRef = useRef<maplibregl.Map | null>(null);

  // Auto-select first event once loaded
  useEffect(() => {
    if (mapEvents.length > 0 && !selectedEvent) {
      setSelectedEvent(mapEvents[0]);
    }
  }, [mapEvents, selectedEvent]);

  // deck.gl 레이어
  const buildLayers = useCallback(() => [
    ...createStaticLayers(),
    // 선박 분석 데이터 마커 (riskLevel 기반 색상)
    createMarkerLayer(
      'ais-vessels',
      vesselMarkers.map((v): MarkerData => {
        const level = v.item.algorithms.riskScore.level;
        const color = getAlertLevelHex(level);
        return {
          lat: v.lat,
          lng: v.lng,
          color,
          radius: level === 'CRITICAL' ? 900 : level === 'HIGH' ? 750 : 600,
          label: v.item.mmsi,
        };
      }),
    ),
    // 이벤트 경보 반경 원
    createRadiusLayer(
      'alert-radius',
      mapEvents.map((evt) => ({
        lat: evt.lat,
        lng: evt.lng,
        radius: 8000,
        color: EVENT_COLORS[evt.type] || '#ef4444',
      })),
      0.08,
    ),
    // 이벤트 마커 (선택 시 크기 강조)
    createMarkerLayer(
      'event-markers',
      mapEvents.map((evt) => ({
        lat: evt.lat,
        lng: evt.lng,
        color: EVENT_COLORS[evt.type] || '#ef4444',
        radius: evt.id === selectedEvent?.id ? 1600 : 1100,
      })),
    ),
  ], [selectedEvent, mapEvents, vesselMarkers]);

  useMapLayers(mapRef, buildLayers, [selectedEvent, mapEvents, vesselMarkers]);

  // deck.gl onClick
  const handleMapClick = useCallback((info: unknown) => {
    const pickInfo = info as { layer?: { id: string }; index?: number };
    if (pickInfo.layer?.id === 'event-markers' && pickInfo.index != null) {
      const evt = mapEvents[pickInfo.index];
      if (evt) setSelectedEvent(evt);
    }
  }, [mapEvents]);

  // 지도 인스턴스 접근 (flyTo용)
  const handleMapReady = useCallback((map: maplibregl.Map) => {
    mapInstanceRef.current = map;
    const first = mapEvents[0];
    if (first) {
      map.flyTo({ center: [first.lng, first.lat], zoom: 9, speed: 0.6 });
    }
  }, [mapEvents]);

  // 선택 이벤트 변경 시 지도 포커스
  useEffect(() => {
    const map = mapInstanceRef.current;
    if (!map || !selectedEvent) return;
    if (!map.isStyleLoaded()) return;
    map.flyTo({ center: [selectedEvent.lng, selectedEvent.lat], zoom: 9, speed: 0.6 });
  }, [selectedEvent]);

  return (
    <PageContainer fullBleed className="flex gap-5 h-[calc(100vh-7rem)]">
      {/* 좌측: 이벤트 목록 + 지도 */}
      <div className="flex-1 flex gap-4 min-w-0">
        {/* 이벤트 카드 목록 */}
        <div className="w-[260px] shrink-0 space-y-3">
          <div>
            <h2 className="text-lg font-bold text-heading">실시간 이벤트</h2>
            <p className="text-[11px] text-hint mt-0.5">현재 진행 중인 의심 활동</p>
          </div>

          {loading && (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="w-5 h-5 text-blue-400 animate-spin" />
              <span className="ml-2 text-[11px] text-hint">로드 중...</span>
            </div>
          )}

          {!serviceAvailable && !loading && (
            <div className="p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-lg">
              <div className="flex items-center gap-2">
                <WifiOff className="w-4 h-4 text-yellow-400" />
                <span className="text-[11px] text-yellow-400 font-medium">분석 서비스 오프라인</span>
              </div>
              <p className="text-[10px] text-hint mt-1">이벤트 데이터만 표시됩니다.</p>
            </div>
          )}

          <div className="space-y-2">
            {mapEvents.map((evt) => {
              const IconComp = eventIconMap[evt.type] || AlertTriangle;
              const isSelected = selectedEvent?.id === evt.id;
              return (
                <div
                  key={evt.id}
                  onClick={() => setSelectedEvent(evt)}
                  className={`p-3 rounded-lg border cursor-pointer transition-all ${
                    isSelected
                      ? 'bg-card border-blue-500/40'
                      : 'bg-card border-[#1F2F3E] hover:border-blue-600/30'
                  }`}
                >
                  <div className="flex items-center justify-between mb-1.5">
                    <div className="flex items-center gap-2">
                      <IconComp className="w-4 h-4 text-muted-foreground" />
                      <span className="text-sm font-semibold text-heading">{evt.type}</span>
                    </div>
                    <Pin className="w-3.5 h-3.5 text-hint hover:text-orange-400 transition-colors" />
                  </div>
                  <div className="text-[11px] text-hint mb-2">{evt.mmsi} · {evt.nationality} · {evt.time}</div>
                  <RiskBar value={evt.risk} size="sm" />
                </div>
              );
            })}
            {!loading && mapEvents.length === 0 && (
              <div className="text-[11px] text-hint text-center py-4">활성 이벤트가 없습니다.</div>
            )}
          </div>
        </div>

        {/* 지도 영역 */}
        <div className="flex-1 relative rounded-xl overflow-hidden">
          <BaseMap ref={mapRef} center={[36.8, 125.3]} zoom={8} height="100%" className="min-h-[400px]" onClick={handleMapClick} onMapReady={handleMapReady} />
          {/* 범례 */}
          <div className="absolute bottom-3 left-3 z-[1000] bg-background/90 backdrop-blur-sm border border-border rounded-lg px-3 py-2">
            <div className="text-[9px] text-muted-foreground font-bold mb-1">선박 범례</div>
            <div className="space-y-0.5">
              {[
                { color: '#ef4444', label: 'CRITICAL' },
                { color: '#f97316', label: 'HIGH' },
                { color: '#3b82f6', label: 'MEDIUM' },
                { color: '#6b7280', label: 'LOW' },
              ].map((l) => (
                <div key={l.label} className="flex items-center gap-1.5">
                  <div className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: l.color }} />
                  <span className="text-[8px] text-muted-foreground">{l.label}</span>
                </div>
              ))}
            </div>
            <div className="flex items-center gap-3 mt-1 pt-1 border-t border-border">
              <div className="flex items-center gap-1"><div className="w-3 h-0 border-t border-dashed border-red-500/50" /><span className="text-[7px] text-hint">EEZ</span></div>
              <div className="flex items-center gap-1"><div className="w-3 h-0 border-t border-dashed border-orange-500/60" /><span className="text-[7px] text-hint">NLL</span></div>
            </div>
          </div>
          {/* 실시간 표시 */}
          <div className="absolute top-3 left-3 z-[1000] flex items-center gap-2 bg-background/90 backdrop-blur-sm border border-border rounded-lg px-3 py-1.5">
            <div className="w-2 h-2 rounded-full bg-red-500 animate-pulse" />
            <span className="text-[10px] text-red-400 font-bold">LIVE</span>
            <span className="text-[9px] text-hint">경보 {mapEvents.length}건 · 분석 {vesselItems.length}척</span>
          </div>
        </div>
      </div>

      {/* 우측: 이벤트 상세 패널 */}
      {selectedEvent && (
        <div className="w-[300px] shrink-0 space-y-3 overflow-y-auto">
          <h3 className="text-base font-bold text-heading">이벤트 상세</h3>

          {/* 선박 정보 카드 */}
          <div className="bg-red-950/40 border border-red-900/40 rounded-xl p-4">
            <div className="flex items-center gap-3">
              <div className="w-9 h-9 bg-red-600/30 rounded-lg flex items-center justify-center">
                <Ship className="w-4.5 h-4.5 text-red-400" />
              </div>
              <div>
                <div className="text-heading font-bold text-sm">{selectedEvent.vesselName}</div>
                <div className="text-[10px] text-muted-foreground">{selectedEvent.id}</div>
                <div className="text-[10px] text-hint">{selectedEvent.mmsi} · {selectedEvent.nationality} · {selectedEvent.time}</div>
              </div>
            </div>
          </div>

          {/* 위험도 점수 */}
          <Card className="bg-surface-overlay border-slate-700/40">
            <CardContent className="p-4">
              <div className="text-[10px] text-muted-foreground mb-1">위험도 점수</div>
              <div className="flex items-baseline gap-1 mb-2">
                <span className="text-3xl font-bold text-red-400">{Math.round(selectedEvent.risk * 100)}</span>
                <span className="text-sm text-hint">/100</span>
              </div>
              <div className="h-2 bg-switch-background rounded-full overflow-hidden">
                <div
                  className="h-2 bg-gradient-to-r from-red-600 to-red-400 rounded-full transition-all"
                  style={{ width: `${selectedEvent.risk * 100}%` }}
                />
              </div>
            </CardContent>
          </Card>

          {/* AI 판단 근거 */}
          <Card className="bg-surface-overlay border-slate-700/40">
            <CardContent className="p-4">
              <div className="flex items-center gap-2 mb-3">
                <Zap className="w-4 h-4 text-blue-400" />
                <span className="text-sm text-heading font-medium">AI 판단 근거</span>
                <Badge intent="critical" size="md">신뢰도: High</Badge>
              </div>
              <div className="space-y-3">
                <div className="border-l-2 border-red-500 pl-3">
                  <div className="flex items-center gap-1.5 text-xs">
                    <AlertTriangle className="w-3 h-3 text-red-400" />
                    <span className="text-red-400 font-medium">{selectedEvent.type}</span>
                  </div>
                  <div className="text-[10px] text-hint mt-0.5">선박: {selectedEvent.vesselName} ({selectedEvent.mmsi})</div>
                </div>
                <div className="border-l-2 border-orange-500 pl-3">
                  <div className="flex items-center gap-1.5 text-xs">
                    <Activity className="w-3 h-3 text-orange-400" />
                    <span className="text-orange-400 font-medium">위치 정보</span>
                  </div>
                  <div className="text-[10px] text-hint mt-0.5">좌표: {selectedEvent.lat.toFixed(4)}, {selectedEvent.lng.toFixed(4)}</div>
                </div>
                <div className="border-l-2 border-green-500 pl-3">
                  <div className="flex items-center gap-1.5 text-xs">
                    <Clock className="w-3 h-3 text-green-400" />
                    <span className="text-green-400 font-medium">발생 시각</span>
                  </div>
                  <div className="text-[10px] text-hint mt-0.5">{selectedEvent.time}</div>
                </div>
              </div>
              <p className="text-[10px] text-hint mt-3">이 판단 근거는 AI 모델 분석 결과이며, 최종 판단은 관리자가 수행합니다.</p>
            </CardContent>
          </Card>
        </div>
      )}
    </PageContainer>
  );
}
