import { useEffect, useState, useMemo, useRef, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Card, CardContent } from '@shared/components/ui/card';
import { Badge } from '@shared/components/ui/badge';
import { Select } from '@shared/components/ui/select';
import { PageContainer, PageHeader } from '@shared/components/layout';
import { DataTable, type DataColumn } from '@shared/components/common/DataTable';
import { EyeOff, AlertTriangle, Loader2, Filter } from 'lucide-react';
import { BaseMap, createStaticLayers, createMarkerLayer, createRadiusLayer, useMapLayers, type MapHandle } from '@lib/map';
import type { MarkerData } from '@lib/map';
import { getDarkVessels, type VesselAnalysis } from '@/services/analysisApi';
import { formatDateTime } from '@shared/utils/dateFormat';
import { getRiskIntent } from '@shared/constants/statusIntent';
import { useSettingsStore } from '@stores/settingsStore';
import { DarkDetailPanel } from './components/DarkDetailPanel';

/* SFR-09: Dark Vessel 탐지 — prediction 직접 API 기반 */

interface Suspect {
  id: string;
  mmsi: string;
  name: string;
  flag: string;
  darkTier: string;
  darkScore: number;
  darkPatterns: string;
  risk: number;
  gap: number;
  lastAIS: string;
  lat: number;
  lng: number;
  [key: string]: unknown;
}

function deriveFlag(mmsi: string): string {
  if (mmsi.startsWith('412')) return '중국';
  if (mmsi.startsWith('440') || mmsi.startsWith('441')) return '한국';
  return '미상';
}

const TIER_HEX: Record<string, string> = {
  CRITICAL: '#ef4444',
  HIGH: '#f97316',
  WATCH: '#eab308',
  NONE: '#6b7280',
};

function mapToSuspect(v: VesselAnalysis, idx: number): Suspect {
  const feat = v.features ?? {};
  const darkTier = (feat.dark_tier as string) ?? 'NONE';
  const darkScore = (feat.dark_suspicion_score as number) ?? 0;
  const patterns = (feat.dark_patterns as string[]) ?? [];

  // 위치: lat/lon이 없으면 features.gap_start_lat/lon 사용
  const lat = (v.lat && v.lat !== 0) ? v.lat : (feat.gap_start_lat as number) ?? 0;
  const lon = (v.lon && v.lon !== 0) ? v.lon : (feat.gap_start_lon as number) ?? 0;

  return {
    id: `DV-${String(idx + 1).padStart(3, '0')}`,
    mmsi: v.mmsi,
    name: v.vesselType || v.mmsi,
    flag: deriveFlag(v.mmsi),
    darkTier,
    darkScore,
    darkPatterns: patterns.join(', ') || '-',
    risk: v.riskScore ?? 0,
    gap: v.gapDurationMin ?? 0,
    lastAIS: formatDateTime(v.analyzedAt),
    lat,
    lng: lon,
  };
}

export function DarkVesselDetection() {
  const { t } = useTranslation('detection');
  const { t: tc } = useTranslation('common');
  const lang = useSettingsStore((s) => s.language);
  const navigate = useNavigate();

  const [tierFilter, setTierFilter] = useState<string>('');
  const [selectedMmsi, setSelectedMmsi] = useState<string | null>(null);

  const cols: DataColumn<Suspect>[] = useMemo(() => [
    { key: 'id', label: 'ID', width: '70px',
      render: (v) => <span className="text-hint font-mono text-[10px]">{v as string}</span> },
    { key: 'darkTier', label: '등급', width: '80px', sortable: true,
      render: (v) => {
        const tier = v as string;
        return <Badge intent={getRiskIntent(tier === 'CRITICAL' ? 90 : tier === 'HIGH' ? 60 : tier === 'WATCH' ? 40 : 10)} size="sm">{tier}</Badge>;
      } },
    { key: 'darkScore', label: '의심점수', width: '80px', align: 'center', sortable: true,
      render: (v) => {
        const n = v as number;
        return <span className={`font-bold font-mono ${n >= 70 ? 'text-red-400' : n >= 50 ? 'text-orange-400' : 'text-yellow-400'}`}>{n}</span>;
      } },
    { key: 'name', label: '선박 유형', sortable: true,
      render: (v) => <span className="text-cyan-400 font-medium">{v as string}</span> },
    { key: 'mmsi', label: 'MMSI', width: '100px',
      render: (v) => {
        const mmsi = v as string;
        return (
          <button type="button" className="text-cyan-400 hover:text-cyan-300 hover:underline font-mono text-[10px]"
            onClick={(e) => { e.stopPropagation(); navigate(`/vessel/${mmsi}`); }}>
            {mmsi}
          </button>
        );
      } },
    { key: 'flag', label: '국적', width: '50px' },
    { key: 'gap', label: 'AIS 공백', width: '80px', align: 'right', sortable: true,
      render: (v) => {
        const min = v as number;
        return <span className="text-label font-mono text-[10px]">{min > 0 ? `${min}분` : '-'}</span>;
      } },
    { key: 'risk', label: '위험도', width: '70px', align: 'center', sortable: true,
      render: (v) => {
        const n = v as number;
        return <span className={`font-bold ${n >= 70 ? 'text-red-400' : n >= 50 ? 'text-yellow-400' : 'text-green-400'}`}>{n}</span>;
      } },
    { key: 'darkPatterns', label: '의심 패턴', minWidth: '120px',
      render: (v) => <span className="text-hint text-[9px]">{v as string}</span> },
    { key: 'lastAIS', label: '분석시각', width: '90px',
      render: (v) => <span className="text-muted-foreground text-[10px]">{v as string}</span> },
  ], [tc, lang, navigate]);

  const [rawData, setRawData] = useState<VesselAnalysis[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  // 선택된 선박의 원본 VesselAnalysis 조회
  const selectedVessel = useMemo(
    () => selectedMmsi ? rawData.find(v => v.mmsi === selectedMmsi) ?? null : null,
    [rawData, selectedMmsi],
  );

  const loadData = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const res = await getDarkVessels({ hours: 1, size: 500 });
      setRawData(res.content);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : '데이터를 불러올 수 없습니다');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { loadData(); }, [loadData]);

  // 30초 자동 갱신 (깜박임 없음 — loading 상태 변경 없이 데이터만 교체)
  useEffect(() => {
    const timer = setInterval(async () => {
      try {
        const res = await getDarkVessels({ hours: 1, size: 500 });
        setRawData(res.content);
      } catch { /* silent */ }
    }, 30_000);
    return () => clearInterval(timer);
  }, []);

  const DATA: Suspect[] = useMemo(() => {
    let items = rawData.map((v, i) => mapToSuspect(v, i));
    if (tierFilter) {
      items = items.filter((d) => d.darkTier === tierFilter);
    }
    // 의심 점수 내림차순 정렬
    return items.sort((a, b) => b.darkScore - a.darkScore);
  }, [rawData, tierFilter]);

  // KPI 카운트
  const tierCounts = useMemo(() => {
    const all = rawData.map((v) => ((v.features ?? {}).dark_tier as string) ?? 'NONE');
    return {
      total: all.length,
      CRITICAL: all.filter((t) => t === 'CRITICAL').length,
      HIGH: all.filter((t) => t === 'HIGH').length,
      WATCH: all.filter((t) => t === 'WATCH').length,
    };
  }, [rawData]);

  const mapRef = useRef<MapHandle>(null);

  const buildLayers = useCallback(() => {
    const validData = DATA.filter((d) => d.lat !== 0 && d.lng !== 0);
    const layers = [
      ...createStaticLayers(),
      // 전체 선박 마커 (tier별 색상)
      createMarkerLayer(
        'dv-markers',
        validData.map((d) => ({
          lat: d.lat, lng: d.lng,
          color: TIER_HEX[d.darkTier] || '#6b7280',
          radius: d.darkScore >= 70 ? 1000 : 600,
          label: `${d.id}`,
        } as MarkerData)),
      ),
      // CRITICAL 위험 반경
      createRadiusLayer(
        'dv-radius',
        validData.filter((d) => d.darkScore >= 70).map((d) => ({
          lat: d.lat, lng: d.lng, radius: 10000,
          color: TIER_HEX[d.darkTier] || '#ef4444',
        })),
        0.08,
      ),
    ];

    // 클릭 선택 선박 하이라이트 (흰색 원 + 큰 마커)
    if (selectedMmsi) {
      const target = validData.find(d => d.mmsi === selectedMmsi);
      if (target) {
        layers.push(
          createRadiusLayer(
            'dv-highlight',
            [{ lat: target.lat, lng: target.lng, radius: 15000, color: '#ffffff' }],
            0.15,
          ),
          createMarkerLayer(
            'dv-highlight-marker',
            [{ lat: target.lat, lng: target.lng, color: '#ffffff', radius: 2000, label: `${target.mmsi}` } as MarkerData],
          ),
        );
      }
    }

    return layers;
  }, [DATA, selectedMmsi]);

  useMapLayers(mapRef, buildLayers, [DATA, selectedMmsi]);

  return (
    <>
    <PageContainer>
      <PageHeader
        icon={EyeOff}
        iconColor="text-red-400"
        title={t('darkVessel.title')}
        description={t('darkVessel.desc')}
        actions={
          <div className="flex items-center gap-1">
            <Filter className="w-3.5 h-3.5 text-hint" />
            <Select size="sm" value={tierFilter} onChange={(e) => setTierFilter(e.target.value)}
              title="등급 필터" className="w-32">
              <option value="">전체 등급</option>
              <option value="CRITICAL">CRITICAL</option>
              <option value="HIGH">HIGH</option>
              <option value="WATCH">WATCH</option>
            </Select>
          </div>
        }
      />

      {error && <div className="text-xs text-red-400">에러: {error}</div>}

      {loading && (
        <div className="flex items-center justify-center py-8 text-muted-foreground">
          <Loader2 className="w-5 h-5 animate-spin" />
        </div>
      )}

      {/* KPI — tier 기반 */}
      <div className="flex gap-2">
        {[
          { l: '전체', v: tierCounts.total, c: 'text-red-400', filter: '' },
          { l: 'CRITICAL', v: tierCounts.CRITICAL, c: 'text-red-400', filter: 'CRITICAL' },
          { l: 'HIGH', v: tierCounts.HIGH, c: 'text-orange-400', filter: 'HIGH' },
          { l: 'WATCH', v: tierCounts.WATCH, c: 'text-yellow-400', filter: 'WATCH' },
        ].map((k) => (
          <div key={k.l}
            onClick={() => setTierFilter(k.filter)}
            className={`flex-1 flex items-center gap-2 px-3 py-2 rounded-xl border cursor-pointer transition-colors ${
              tierFilter === k.filter ? 'bg-card border-blue-500/30' : 'bg-card border-border hover:border-border'
            }`}>
            <AlertTriangle className={`w-4 h-4 ${k.c}`} />
            <span className={`text-base font-bold ${k.c}`}>{k.v}</span>
            <span className="text-[9px] text-hint">{k.l}</span>
          </div>
        ))}
      </div>

      <DataTable data={DATA} columns={cols} pageSize={10}
        searchPlaceholder="선박유형, MMSI, 패턴 검색..."
        searchKeys={['name', 'mmsi', 'darkPatterns', 'flag', 'darkTier']}
        exportFilename="Dark_Vessel_탐지"
        onRowClick={(row) => setSelectedMmsi(row.mmsi)} />

      {/* 탐지 위치 지도 */}
      <Card>
        <CardContent className="p-0 relative">
          <BaseMap ref={mapRef} center={[36.5, 127.5]} zoom={7} height={450} className="rounded-lg overflow-hidden" />
          {/* 범례 — tier 기반 */}
          <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.5">Dark Tier</div>
            <div className="space-y-1">
              {(['CRITICAL', 'HIGH', 'WATCH', 'NONE'] as const).map((tier) => (
                <div key={tier} className="flex items-center gap-1.5">
                  <div className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: TIER_HEX[tier] }} />
                  <span className="text-[8px] text-muted-foreground">{tier}</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">{tierCounts.CRITICAL}척</span>
            <span className="text-[9px] text-hint">CRITICAL Dark Vessel</span>
          </div>
        </CardContent>
      </Card>
    </PageContainer>

    {/* 판정 상세 사이드 패널 */}
    {selectedVessel && (
      <DarkDetailPanel vessel={selectedVessel} onClose={() => setSelectedMmsi(null)} />
    )}
    </>
  );
}
