/**
 * 드론 지리정보 검색 패널
 * - 건물/측점명 → 해당 프레임 탐색
 * - 현재 프레임 → 보이는 건물/측점 목록
 */

import React, { useState, useEffect, useCallback, useRef } from 'react';
import { useGeoStore } from '../../store/geoStore';
import { findFramesForPoi, findPoisForFrame } from '../../utils/geoSearch';
import type { GeoPoint, FrameMatch, PoiInFrame } from '../../types/geo';

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

type Tab = 'search' | 'reverse';

export default function GeoSearch({ currentFrame, fps, onSeekToFrame }: Props) {
  const [tab, setTab] = useState<Tab>('search');
  const [query, setQuery] = useState('');
  const [suggestions, setSuggestions] = useState<GeoPoint[]>([]);
  const [searchResult, setSearchResult] = useState<{ poi: GeoPoint; frames: FrameMatch[] } | null>(null);
  const [reverseResult, setReverseResult] = useState<PoiInFrame[] | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  // 클라이언트 지리정보 스토어 구독 (서버 /api/geo/* 대체)
  const loaded = useGeoStore(s => s.loaded);
  const frames = useGeoStore(s => s.frames);
  const pois = useGeoStore(s => s.pois);
  const stations = useGeoStore(s => s.stations);

  // POI 목록 (자동완성용): 측점 + 건물 통합 (서버 /api/geo/pois 동치)
  const allPois = React.useMemo<GeoPoint[]>(
    () => (loaded ? [...stations, ...pois] : []),
    [loaded, stations, pois],
  );

  // 자동완성 필터링
  useEffect(() => {
    if (!query.trim()) { setSuggestions([]); return; }
    const q = query.toLowerCase();
    setSuggestions(allPois.filter(p => p.title.toLowerCase().includes(q)).slice(0, 10));
  }, [query, allPois]);

  // 건물/측점명으로 프레임 검색 (클라이언트 검색 — 서버 /api/geo/search 대체)
  const handleSearch = useCallback((q?: string) => {
    const searchQ = (q ?? query).trim();
    if (!searchQ) return;
    setLoading(true);
    setError('');
    setSuggestions([]);
    try {
      if (!loaded) { setError('폴더를 먼저 선택하세요'); setSearchResult(null); return; }
      const origin = useGeoStore.getState().origin;
      const combined = [...stations, ...pois];
      const result = findFramesForPoi(frames, combined, searchQ, 1.0, 1500, 0, origin);
      if (!result.poi) { setError('일치하는 건물/측점 없음'); setSearchResult(null); return; }
      setSearchResult({ poi: result.poi, frames: result.frames });
    } finally {
      setLoading(false);
    }
  }, [query, loaded, frames, stations, pois]);

  // 현재 프레임 역조회 (클라이언트 검색 — 서버 /api/geo/frame/{n} 대체)
  const handleReverse = useCallback(() => {
    setLoading(true);
    setError('');
    try {
      if (!loaded) { setReverseResult([]); return; }
      const origin = useGeoStore.getState().origin;
      const combined = [...stations, ...pois];
      const result = findPoisForFrame(frames, combined, currentFrame, 1.0, 0, origin);
      setReverseResult(result.pois);
    } finally {
      setLoading(false);
    }
  }, [currentFrame, loaded, frames, stations, pois]);

  // 탭 전환/프레임 변경/데이터 로드 시 역조회 자동 실행
  useEffect(() => {
    if (tab === 'reverse') handleReverse();
  }, [tab, currentFrame, handleReverse]);

  const formatDist = (m: number) =>
    m >= 1000 ? `${(m / 1000).toFixed(2)}km` : `${Math.round(m)}m`;

  const formatAngle = (deg: number) =>
    `${deg >= 0 ? '+' : ''}${deg.toFixed(1)}°`;

  return (
    <div className="flex flex-col h-full text-sm">
      {/* 탭 */}
      <div className="flex border-b border-gray-700 flex-shrink-0">
        <button
          className={`flex-1 py-2 text-xs font-medium transition-colors ${tab === 'search' ? 'text-blue-400 border-b-2 border-blue-400' : 'text-gray-500 hover:text-gray-300'}`}
          onClick={() => setTab('search')}
        >
          건물 → 프레임
        </button>
        <button
          className={`flex-1 py-2 text-xs font-medium transition-colors ${tab === 'reverse' ? 'text-blue-400 border-b-2 border-blue-400' : 'text-gray-500 hover:text-gray-300'}`}
          onClick={() => setTab('reverse')}
        >
          프레임 → 건물
        </button>
      </div>

      {/* 검색 탭 */}
      {tab === 'search' && (
        <div className="flex flex-col h-full min-h-0">
          <div className="p-2 flex-shrink-0 relative">
            <div className="flex gap-1">
              <input
                className="flex-1 bg-gray-800 border border-gray-600 rounded px-2 py-1 text-xs text-white placeholder-gray-500 focus:outline-none focus:border-blue-500"
                placeholder="건물명 또는 측점번호..."
                value={query}
                onChange={e => setQuery(e.target.value)}
                onKeyDown={e => e.key === 'Enter' && handleSearch()}
              />
              <button
                onClick={() => handleSearch()}
                disabled={loading}
                className="px-2 py-1 bg-blue-600 hover:bg-blue-500 disabled:bg-gray-700 rounded text-xs transition-colors"
              >
                {loading ? '…' : '검색'}
              </button>
            </div>
            {/* 자동완성 */}
            {suggestions.length > 0 && (
              <div className="absolute left-2 right-2 mt-0.5 bg-gray-800 border border-gray-600 rounded shadow-lg z-50 max-h-48 overflow-y-auto">
                {suggestions.map((s, i) => (
                  <button
                    key={i}
                    className="w-full text-left px-3 py-1.5 hover:bg-gray-700 text-xs text-white flex items-center gap-2"
                    onClick={() => { setQuery(s.title); handleSearch(s.title); }}
                  >
                    <span className={`text-xs px-1 rounded ${s.type === 'station' ? 'bg-green-800 text-green-300' : 'bg-blue-900 text-blue-300'}`}>
                      {s.type === 'station' ? '측점' : s.category || 'POI'}
                    </span>
                    {s.title}
                  </button>
                ))}
              </div>
            )}
          </div>

          {error && <div className="px-3 py-1 text-xs text-red-400">{error}</div>}

          {searchResult && (
            <div className="flex-1 overflow-y-auto min-h-0">
              {/* POI 정보 */}
              <div className="px-3 py-2 bg-gray-800/50 border-b border-gray-700 flex-shrink-0">
                <div className="text-xs font-semibold text-white">{searchResult.poi.title}</div>
                <div className="text-xs text-gray-400 mt-0.5">
                  {searchResult.poi.category} · 표고 {searchResult.poi.z.toFixed(1)}m
                </div>
                <div className="text-xs text-gray-500">
                  {searchResult.poi.lat.toFixed(6)}, {searchResult.poi.lon.toFixed(6)}
                </div>
                <div className="text-xs text-blue-400 mt-1">
                  {searchResult.frames.length}개 관측 구간
                </div>
              </div>

              {searchResult.frames.length === 0 && (
                <div className="text-xs text-gray-500 p-3 text-center">
                  카메라 시야에 들어오는 프레임 없음<br />
                  <button
                    className="mt-1 text-blue-400 hover:text-blue-300"
                    onClick={() => handleSearch()}
                  >
                    여백 늘려서 재검색
                  </button>
                </div>
              )}

              <div className="space-y-1 p-1">
                {searchResult.frames.map((fm, i) => (
                  <button
                    key={fm.frame}
                    className="w-full text-left px-2 py-2 rounded hover:bg-gray-700 transition-colors border border-gray-700/50"
                    onClick={() => onSeekToFrame(fm.frame)}
                  >
                    <div className="flex items-center justify-between">
                      <span className="text-xs text-white font-mono font-bold">
                        #{i + 1}  Frame {fm.frame}
                      </span>
                      <span className="text-xs text-gray-300">{formatDist(fm.distance)}</span>
                    </div>
                    {(fm as any).groupSize > 1 && (
                      <div className="text-xs text-yellow-600 mt-0.5">
                        구간 {(fm as any).groupStart}~{(fm as any).groupEnd} ({(fm as any).groupSize}프레임)
                      </div>
                    )}
                    <div className="flex gap-2 mt-0.5">
                      <span className="text-xs text-gray-400">수평 {formatAngle(fm.bearingDiff)}</span>
                      <span className="text-xs text-gray-400">수직 {formatAngle(fm.elevationDiff)}</span>
                      <span className="text-xs text-gray-600">
                        화면 ({(fm.pixelX * 100).toFixed(0)}%, {(fm.pixelY * 100).toFixed(0)}%)
                      </span>
                    </div>
                  </button>
                ))}
              </div>
            </div>
          )}
        </div>
      )}

      {/* 역조회 탭 */}
      {tab === 'reverse' && (
        <div className="flex flex-col h-full min-h-0">
          <div className="px-3 py-2 bg-gray-800/50 border-b border-gray-700 flex-shrink-0 flex items-center justify-between">
            <div>
              <span className="text-xs text-gray-400">현재 프레임: </span>
              <span className="text-xs text-white font-mono">#{currentFrame}</span>
            </div>
            <button
              onClick={handleReverse}
              disabled={loading}
              className="text-xs text-blue-400 hover:text-blue-300 disabled:text-gray-600"
            >
              {loading ? '조회 중…' : '새로고침'}
            </button>
          </div>

          {error && <div className="px-3 py-1 text-xs text-red-400">{error}</div>}

          <div className="flex-1 overflow-y-auto min-h-0">
            {reverseResult && reverseResult.length === 0 && (
              <div className="text-xs text-gray-500 p-3 text-center">
                현재 프레임 시야에 건물/측점 없음
              </div>
            )}
            {reverseResult && reverseResult.length > 0 && (
              <div className="space-y-0.5 p-1">
                {reverseResult.map((item, i) => (
                  <div key={i} className="px-2 py-1.5 rounded bg-gray-800/30 hover:bg-gray-800/60">
                    <div className="flex items-center justify-between">
                      <span className="text-xs text-white">{item.poi.title}</span>
                      <span className="text-xs text-gray-400">{formatDist(item.distance)}</span>
                    </div>
                    <div className="flex gap-2 mt-0.5 items-center">
                      <span className={`text-xs px-1 rounded ${item.poi.type === 'station' ? 'bg-green-800 text-green-300' : 'bg-blue-900 text-blue-300'}`}>
                        {item.poi.type === 'station' ? '측점' : item.poi.category}
                      </span>
                      <span className="text-xs text-gray-500">
                        수평 {formatAngle(item.bearingDiff)} / 수직 {formatAngle(item.elevationDiff)}
                      </span>
                    </div>
                    <div className="text-xs text-gray-600 mt-0.5">
                      화면 위치 ({(item.pixelX * 100).toFixed(0)}%, {(item.pixelY * 100).toFixed(0)}%)
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}
