/**
 * 측점 검증 패널
 * - 측점 목록을 클릭하면 해당 측점이 가장 잘 보이는 프레임으로 이동
 * - 이동 결과(거리, 화면 위치)를 표시하여 계산 정확도 검증
 */

import React, { useState, useEffect } from 'react';

interface GeoPoint {
  title: string;
  category: string;
  lat: number;
  lon: number;
  z: number;
  type: 'poi' | 'station';
}

interface FrameMatch {
  frame: number;
  time: number;
  bearingDiff: number;
  elevationDiff: number;
  distance: number;
  pixelX: number;
  pixelY: number;
  groupSize?: number;
  groupStart?: number;
  groupEnd?: number;
}

interface StationResult {
  frames: FrameMatch[];
  poi: GeoPoint;
}

interface Props {
  fps: number;
  onSeekToFrame: (frame: number) => void;
}

function stationOrder(title: string): number {
  const m = title.match(/(\d+)[Kk](\d+)/);
  if (!m) return 0;
  return parseInt(m[1]) * 1000 + parseInt(m[2]);
}

export default function StationVerify({ fps, onSeekToFrame }: Props) {
  const [stations, setStations] = useState<GeoPoint[]>([]);
  const [selected, setSelected] = useState<string | null>(null);
  const [result, setResult] = useState<StationResult | null>(null);
  const [loading, setLoading] = useState(false);
  const [seekedFrame, setSeekedFrame] = useState<number | null>(null);

  useEffect(() => {
    fetch('/api/geo/pois')
      .then(r => r.json())
      .then((data: GeoPoint[]) => {
        const s = Array.isArray(data)
          ? data.filter(p => p.type === 'station').sort((a, b) => stationOrder(a.title) - stationOrder(b.title))
          : [];
        setStations(s);
      })
      .catch(() => {});
  }, []);

  const handleClick = async (station: GeoPoint) => {
    setSelected(station.title);
    setResult(null);
    setLoading(true);
    setSeekedFrame(null);
    try {
      const res = await fetch(`/api/geo/search?q=${encodeURIComponent(station.title)}&margin=1.2&maxDist=2000`);
      const data = await res.json();
      if (!res.ok || !data.frames?.length) {
        setResult({ frames: [], poi: data.poi ?? station });
        return;
      }
      setResult(data);
      // 가장 중심에 가까운 첫 번째 결과로 이동
      const best = data.frames[0];
      onSeekToFrame(best.frame);
      setSeekedFrame(best.frame);
    } catch {
      setResult(null);
    } finally {
      setLoading(false);
    }
  };

  const pixelQuality = (px: number, py: number) => {
    const dx = Math.abs(px - 0.5);
    const dy = Math.abs(py - 0.5);
    const dist = Math.sqrt(dx * dx + dy * dy);
    if (dist < 0.15) return 'text-green-400';
    if (dist < 0.35) return 'text-yellow-400';
    return 'text-orange-400';
  };

  return (
    <div className="flex flex-col h-full text-sm">
      <div className="px-3 py-2 bg-gray-800/50 border-b border-gray-700 flex-shrink-0">
        <div className="text-xs text-gray-400">측점 클릭 → 최적 프레임 이동 + 검증</div>
        <div className="text-xs text-gray-600 mt-0.5">{stations.length}개 측점</div>
      </div>

      <div className="flex-1 overflow-y-auto min-h-0">
        {/* 선택된 측점 결과 */}
        {selected && (
          <div className="mx-2 my-2 p-2 bg-gray-800 rounded border border-gray-600 flex-shrink-0">
            <div className="text-xs font-bold text-white">{selected}</div>
            {loading && <div className="text-xs text-gray-400 mt-1">검색 중…</div>}
            {!loading && result && result.frames.length === 0 && (
              <div className="text-xs text-red-400 mt-1">카메라 시야에 들어오는 프레임 없음</div>
            )}
            {!loading && result && result.frames.length > 0 && (() => {
              const f = result.frames[0];
              return (
                <>
                  <div className="text-xs text-gray-300 mt-1">
                    F{f.frame} · {f.distance >= 1000 ? `${(f.distance/1000).toFixed(2)}km` : `${Math.round(f.distance)}m`}
                  </div>
                  <div className={`text-xs mt-0.5 font-mono ${pixelQuality(f.pixelX, f.pixelY)}`}>
                    화면 ({(f.pixelX * 100).toFixed(0)}%, {(f.pixelY * 100).toFixed(0)}%)
                    &nbsp;수평 {f.bearingDiff >= 0 ? '+' : ''}{f.bearingDiff.toFixed(1)}°
                  </div>
                  {result.frames.length > 1 && (
                    <div className="flex flex-wrap gap-1 mt-1.5">
                      {result.frames.slice(1).map((fm, i) => (
                        <button
                          key={fm.frame}
                          className="text-[10px] px-1.5 py-0.5 bg-gray-700 hover:bg-gray-600 rounded text-gray-300"
                          onClick={() => { onSeekToFrame(fm.frame); setSeekedFrame(fm.frame); }}
                        >
                          #{i + 2} F{fm.frame}
                        </button>
                      ))}
                    </div>
                  )}
                </>
              );
            })()}
          </div>
        )}

        {/* 측점 목록 */}
        <div className="space-y-px px-1 pb-2">
          {stations.map(st => (
            <button
              key={st.title}
              onClick={() => handleClick(st)}
              className={`w-full text-left px-2 py-2 rounded transition-colors flex items-center justify-between ${
                selected === st.title
                  ? 'bg-yellow-500/20 border border-yellow-500/50'
                  : 'hover:bg-gray-800 border border-transparent'
              }`}
            >
              <span className={`text-xs font-mono font-bold ${selected === st.title ? 'text-yellow-400' : 'text-gray-200'}`}>
                {st.title}
              </span>
              <span className="text-[10px] text-gray-600">
                {st.z.toFixed(0)}m
              </span>
            </button>
          ))}
        </div>
      </div>
    </div>
  );
}
