/**
 * 선박 검색 훅
 * 참조: mda-react-front/src/hooks/useBottomSearch.ts
 *
 * 검색 조건:
 * - 통합모드 ON: targetId, shipName에서 검색
 * - 통합모드 OFF: originalTargetId (레이더 제외), shipName에서 검색
 * - 공백/특수문자 제거, 대소문자 무시
 * - 최대 10개 결과 반환
 *
 * 성능 최적화:
 * - 한글: 최소 2자, shipName만 검색
 * - 영문/숫자: 최소 3자
 * - 디바운싱 (200ms)
 * - 조기 종료 (결과 10개 도달 시)
 */
import { useState, useCallback, useRef, useEffect } from 'react';
import { fromLonLat } from 'ol/proj';
import useShipStore from '../stores/shipStore';
import { useMapStore } from '../stores/mapStore';
import useTrackingModeStore, { isWithinRadius, NM_TO_METERS } from '../stores/trackingModeStore';

// 레이더 신호원 코드
const SIGNAL_SOURCE_CODE_RADAR = '000005';

// 최대 검색 결과 수
const MAX_RESULTS = 10;

// 디바운스 시간 (ms)
const DEBOUNCE_MS = 200;

// 한글 정규식
const KOREAN_REGEX = /[가-힣ㄱ-ㅎㅏ-ㅣ]/;

/**
 * 검색어가 한글을 포함하는지 확인
 * @param {string} text
 * @returns {boolean}
 */
function containsKorean(text) {
  return KOREAN_REGEX.test(text);
}

/**
 * 검색어 정규화
 * - 공백 제거
 * - 특수문자 제거 (알파벳, 숫자, 한글만 유지)
 * - 소문자 변환
 * @param {string} text
 * @returns {string}
 */
function normalizeSearchText(text) {
  if (!text) return '';
  return text
    .toLowerCase()
    .replace(/[\s\-_.,:;!@#$%^&*()+=\[\]{}|\\/<>?'"]/g, '')
    .trim();
}

/**
 * 최소 검색 길이 확인
 * - 한글 포함: 최소 2자
 * - 영문/숫자만: 최소 3자
 * @param {string} originalText - 원본 입력값
 * @param {string} normalizedText - 정규화된 검색어
 * @returns {boolean}
 */
function meetsMinLength(originalText, normalizedText) {
  if (!normalizedText) return false;

  const hasKorean = containsKorean(originalText);
  const minLength = hasKorean ? 2 : 3;

  return normalizedText.length >= minLength;
}

/**
 * 선박 검색 훅
 * @returns {Object} { searchValue, setSearchValue, results, handleSearch, handleClickResult, clearSearch }
 */
export default function useShipSearch() {
  const [searchValue, setSearchValueState] = useState('');
  const [results, setResults] = useState([]);

  const map = useMapStore((s) => s.map);
  const features = useShipStore((s) => s.features);
  const isIntegrate = useShipStore((s) => s.isIntegrate);
  const darkSignalIds = useShipStore((s) => s.darkSignalIds);
  const setSelectedShipIds = useShipStore((s) => s.setSelectedShipIds);
  const openDetailModal = useShipStore((s) => s.openDetailModal);

  // 추적 모드 상태
  const trackingMode = useTrackingModeStore((s) => s.mode);
  const trackedShip = useTrackingModeStore((s) => s.trackedShip);
  const radiusNM = useTrackingModeStore((s) => s.radiusNM);

  // 디바운스 타이머 ref
  const debounceTimerRef = useRef(null);

  // 컴포넌트 언마운트 시 타이머 정리
  useEffect(() => {
    return () => {
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current);
      }
    };
  }, []);

  /**
   * 실제 검색 실행 (디바운스 후 호출)
   * @param {string} keyword - 검색어
   */
  const executeSearch = useCallback((keyword) => {
    const normalizedKeyword = normalizeSearchText(keyword);

    // 최소 길이 미달 시 결과 초기화
    if (!meetsMinLength(keyword, normalizedKeyword)) {
      setResults([]);
      return;
    }

    // 반경 필터 상태 확인
    const isRadiusFilterActive = trackingMode === 'ship' && trackedShip !== null;
    let radiusBoundingBox = null;
    let radiusCenter = null;

    if (isRadiusFilterActive && trackedShip?.longitude && trackedShip?.latitude) {
      radiusCenter = { lon: trackedShip.longitude, lat: trackedShip.latitude };
      const LON_DEGREE_METERS = 91000;
      const LAT_DEGREE_METERS = 111000;
      const radiusMeters = radiusNM * NM_TO_METERS;
      const lonDelta = radiusMeters / LON_DEGREE_METERS;
      const latDelta = radiusMeters / LAT_DEGREE_METERS;
      radiusBoundingBox = {
        minLon: radiusCenter.lon - lonDelta,
        maxLon: radiusCenter.lon + lonDelta,
        minLat: radiusCenter.lat - latDelta,
        maxLat: radiusCenter.lat + latDelta,
      };
    }

    const hasKorean = containsKorean(keyword);
    const matchedShips = [];

    // Map을 배열로 변환하여 for...of로 조기 종료 가능하게
    const featuresArray = Array.from(features.entries());

    for (const [featureId, ship] of featuresArray) {
      // 최대 결과 수 도달 시 조기 종료
      if (matchedShips.length >= MAX_RESULTS) break;

      // 다크시그널은 검색 대상에서 제외
      if (darkSignalIds.has(featureId)) continue;

      // 좌표가 없는 선박 제외
      if (!ship.longitude || !ship.latitude) continue;

      // 반경 필터 적용 (추적 모드일 때만)
      if (isRadiusFilterActive && radiusBoundingBox && radiusCenter) {
        const inBounds =
          ship.longitude >= radiusBoundingBox.minLon &&
          ship.longitude <= radiusBoundingBox.maxLon &&
          ship.latitude >= radiusBoundingBox.minLat &&
          ship.latitude <= radiusBoundingBox.maxLat;

        if (!inBounds || !isWithinRadius(ship, radiusCenter.lon, radiusCenter.lat, radiusNM)) {
          continue;
        }
      }

      const shipName = ship.shipName || '';
      const normalizedShipName = normalizeSearchText(shipName);

      let matched = false;

      if (isIntegrate) {
        // 통합모드 ON: targetId, shipName에서 검색
        // isPriority가 있는 선박만 검색 (통합선박 대표)
        if (ship.integrate && !ship.isPriority) continue;

        if (hasKorean) {
          // 한글 검색: shipName만
          matched = normalizedShipName.includes(normalizedKeyword);
        } else {
          // 영문/숫자: targetId, shipName 모두
          const targetId = ship.targetId || '';
          const normalizedTargetId = normalizeSearchText(targetId);
          matched =
            normalizedTargetId.includes(normalizedKeyword) ||
            normalizedShipName.includes(normalizedKeyword);
        }
      } else {
        // 통합모드 OFF: originalTargetId (레이더 제외), shipName에서 검색
        // 레이더 신호원 제외
        if (ship.signalSourceCode === SIGNAL_SOURCE_CODE_RADAR) continue;

        if (hasKorean) {
          // 한글 검색: shipName만
          matched = normalizedShipName.includes(normalizedKeyword);
        } else {
          // 영문/숫자: originalTargetId, shipName 모두
          const originalTargetId = ship.originalTargetId || '';
          const normalizedOriginalTargetId = normalizeSearchText(originalTargetId);
          matched =
            normalizedOriginalTargetId.includes(normalizedKeyword) ||
            normalizedShipName.includes(normalizedKeyword);
        }
      }

      if (matched) {
        matchedShips.push({
          featureId,
          targetId: ship.targetId || '',
          originalTargetId: ship.originalTargetId || '',
          shipName: ship.shipName || '-',
          signalSourceCode: ship.signalSourceCode,
          longitude: ship.longitude,
          latitude: ship.latitude,
          ship,
        });
      }
    }

    setResults(matchedShips);
  }, [features, isIntegrate, darkSignalIds, trackingMode, trackedShip, radiusNM]);

  /**
   * 검색어 변경 핸들러 (디바운스 적용)
   * @param {string} keyword - 검색어
   */
  const setSearchValue = useCallback((keyword) => {
    setSearchValueState(keyword);

    // 빈 입력 시 즉시 결과 초기화
    if (!keyword || keyword.trim().length === 0) {
      setResults([]);
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current);
        debounceTimerRef.current = null;
      }
      return;
    }

    // 디바운스: 타이핑 중에는 검색 지연
    if (debounceTimerRef.current) {
      clearTimeout(debounceTimerRef.current);
    }

    debounceTimerRef.current = setTimeout(() => {
      executeSearch(keyword);
      debounceTimerRef.current = null;
    }, DEBOUNCE_MS);
  }, [executeSearch]);

  /**
   * 검색 결과 클릭 핸들러
   * - 선박 선택 (하이라이트)
   * - 상세 모달 열기
   * - 지도 중심 이동
   * @param {Object} result - 검색 결과 항목
   */
  const handleClickResult = useCallback((result) => {
    if (!map || !result) return;

    const { featureId, longitude, latitude, ship } = result;

    // 선박 선택 (하이라이트 표시)
    setSelectedShipIds([featureId]);

    // 상세 모달 열기
    if (ship) {
      openDetailModal(ship);
    }

    // 지도 중심 이동 (애니메이션)
    const position = fromLonLat([longitude, latitude]);
    map.getView().animate({
      center: position,
      zoom: 14,
      duration: 500,
    });

    // 검색창 초기화
    setSearchValueState('');
    setResults([]);
  }, [map, setSelectedShipIds, openDetailModal]);

  /**
   * 검색 초기화
   */
  const clearSearch = useCallback(() => {
    setSearchValueState('');
    setResults([]);
    if (debounceTimerRef.current) {
      clearTimeout(debounceTimerRef.current);
      debounceTimerRef.current = null;
    }
  }, []);

  /**
   * 엔터키로 첫 번째 결과 선택
   */
  const handleSelectFirst = useCallback(() => {
    if (results.length > 0) {
      handleClickResult(results[0]);
    }
  }, [results, handleClickResult]);

  return {
    searchValue,
    setSearchValue,
    results,
    handleClickResult,
    handleSelectFirst,
    clearSearch,
    isIntegrate,
  };
}
