/**
 * TopBar 컴포넌트
 * 지도 상단 중앙에 배치되는 정보/검색 바
 * - 마우스 커서 좌표 (경도/위도) - 도분초/도 선택 가능
 * - 현재 시간 (KST/UTC 선택 가능)
 * - 선박 검색 (통합모드 ON/OFF에 따른 검색 조건 분기)
 */
import { useState, useEffect, useCallback, useRef } from 'react';
import { toLonLat } from 'ol/proj';
import { useMapStore } from '../../stores/mapStore';
import useTrackingModeStore from '../../stores/trackingModeStore';
import useShipSearch from '../../hooks/useShipSearch';
import PatrolShipSelector from './PatrolShipSelector';
import './TopBar.scss';

/**
 * 십진도를 도분초(DMS) 형식으로 변환
 * @param {number} decimal - 십진도
 * @param {boolean} isLongitude - 경도 여부 (false면 위도)
 * @returns {{ degrees: number, minutes: number, seconds: string, direction: string }}
 */
function decimalToDMS(decimal, isLongitude) {
  const absolute = Math.abs(decimal);
  const degrees = Math.floor(absolute);
  const minutesFloat = (absolute - degrees) * 60;
  const minutes = Math.floor(minutesFloat);
  const seconds = ((minutesFloat - minutes) * 60).toFixed(3);

  let direction;
  if (isLongitude) {
    direction = decimal >= 0 ? 'E' : 'W';
  } else {
    direction = decimal >= 0 ? 'N' : 'S';
  }

  return { degrees, minutes, seconds, direction };
}

/**
 * 십진도를 도(Decimal Degrees) 형식 문자열로 변환
 * @param {number} decimal - 십진도
 * @param {boolean} isLongitude - 경도 여부
 * @returns {string}
 */
function formatDecimalDegrees(decimal, isLongitude) {
  const direction = isLongitude
    ? (decimal >= 0 ? 'E' : 'W')
    : (decimal >= 0 ? 'N' : 'S');
  return `${Math.abs(decimal).toFixed(6)}° ${direction}`;
}

/**
 * 현재 시간을 KST 형식으로 포맷
 * @param {Date} date
 * @returns {{ dateStr: string, timeStr: string, dayOfWeek: string }}
 */
function formatKST(date) {
  const days = ['일', '월', '화', '수', '목', '금', '토'];
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');
  const dayOfWeek = days[date.getDay()];

  return {
    dateStr: `${year}-${month}-${day}`,
    timeStr: `${hours}:${minutes}:${seconds}`,
    dayOfWeek,
  };
}

/**
 * 현재 시간을 UTC 형식으로 포맷
 * @param {Date} date
 * @returns {{ dateStr: string, timeStr: string, dayOfWeek: string }}
 */
function formatUTC(date) {
  const days = ['일', '월', '화', '수', '목', '금', '토'];
  const year = date.getUTCFullYear();
  const month = String(date.getUTCMonth() + 1).padStart(2, '0');
  const day = String(date.getUTCDate()).padStart(2, '0');
  const hours = String(date.getUTCHours()).padStart(2, '0');
  const minutes = String(date.getUTCMinutes()).padStart(2, '0');
  const seconds = String(date.getUTCSeconds()).padStart(2, '0');
  const dayOfWeek = days[date.getUTCDay()];

  return {
    dateStr: `${year}-${month}-${day}`,
    timeStr: `${hours}:${minutes}:${seconds}`,
    dayOfWeek,
  };
}

export default function TopBar() {
  const map = useMapStore((s) => s.map);

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

  // 마우스 좌표 상태
  const [coordinates, setCoordinates] = useState({ lon: null, lat: null });

  // 현재 시간 상태
  const [currentTime, setCurrentTime] = useState(new Date());

  // 설정 상태
  const [coordFormat, setCoordFormat] = useState('dms'); // 'dms' | 'decimal'
  const [timeFormat, setTimeFormat] = useState('kst');   // 'kst' | 'utc'
  const [showSettings, setShowSettings] = useState(false);
  const settingsRef = useRef(null);

  // 검색 훅
  const {
    searchValue,
    setSearchValue,
    results,
    handleClickResult,
    handleSelectFirst,
    clearSearch,
    isIntegrate,
  } = useShipSearch();

  // 검색창 포커스 상태
  const [isSearchFocused, setIsSearchFocused] = useState(false);
  const searchContainerRef = useRef(null);

  // 좌표 업데이트 쓰로틀 ref
  const throttleRef = useRef(null);

  // 마우스 이동 시 좌표 업데이트
  useEffect(() => {
    if (!map) return;

    const handlePointerMove = (evt) => {
      // 쓰로틀: 100ms
      if (throttleRef.current) return;

      throttleRef.current = setTimeout(() => {
        throttleRef.current = null;
      }, 100);

      const pixel = evt.pixel;
      const coord3857 = map.getCoordinateFromPixel(pixel);
      if (coord3857) {
        const [lon, lat] = toLonLat(coord3857);
        setCoordinates({ lon, lat });
      }
    };

    map.on('pointermove', handlePointerMove);

    return () => {
      map.un('pointermove', handlePointerMove);
      if (throttleRef.current) {
        clearTimeout(throttleRef.current);
        throttleRef.current = null;
      }
    };
  }, [map]);

  // 1초마다 시간 업데이트
  useEffect(() => {
    const timer = setInterval(() => {
      setCurrentTime(new Date());
    }, 1000);

    return () => clearInterval(timer);
  }, []);

  // 검색창/설정 외부 클릭 시 닫기
  useEffect(() => {
    const handleClickOutside = (e) => {
      if (searchContainerRef.current && !searchContainerRef.current.contains(e.target)) {
        setIsSearchFocused(false);
      }
      if (settingsRef.current && !settingsRef.current.contains(e.target)) {
        setShowSettings(false);
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  // 검색어 변경 핸들러
  const handleSearchChange = useCallback((e) => {
    setSearchValue(e.target.value);
  }, [setSearchValue]);

  // 엔터키로 첫 번째 결과 선택
  const handleKeyDown = useCallback((e) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      handleSelectFirst();
    } else if (e.key === 'Escape') {
      clearSearch();
      setIsSearchFocused(false);
    }
  }, [handleSelectFirst, clearSearch]);

  // 검색 결과 클릭
  const handleResultClick = useCallback((result) => {
    handleClickResult(result);
    setIsSearchFocused(false);
  }, [handleClickResult]);

  // 설정 토글
  const toggleSettings = useCallback(() => {
    setShowSettings((prev) => !prev);
  }, []);

  /**
   * 문자열 길이 제한 (말줄임)
   */
  const truncateString = (str, maxLength = 20) => {
    if (!str) return '-';
    return str.length > maxLength ? str.slice(0, maxLength) + '...' : str;
  };

  // 좌표 포맷팅 (설정에 따라)
  const renderCoordinate = (value, isLongitude) => {
    if (value === null) return <span>---</span>;

    if (coordFormat === 'dms') {
      const dms = decimalToDMS(value, isLongitude);
      return (
        <>
          <span>{dms.degrees}°</span>
          <span>{dms.minutes}'</span>
          <span>{dms.seconds}"</span>
          <span>{dms.direction}</span>
        </>
      );
    } else {
      return <span>{formatDecimalDegrees(value, isLongitude)}</span>;
    }
  };

  // 시간 포맷팅 (설정에 따라)
  const timeData = timeFormat === 'kst' ? formatKST(currentTime) : formatUTC(currentTime);
  const timeLabel = timeFormat === 'kst' ? 'KST' : 'UTC';

  return (
    <section className="topBar">
      <div className="locationInfo">
        <ul>
          {/* 맵 모드 버튼 */}
          <li>
            <button
              type="button"
              className={`map ${mode === 'map' ? 'active' : ''}`}
              onClick={setMapMode}
            >
              <span className="blind">지도</span>
            </button>
          </li>

          {/* 경도 */}
          <li className="divider">
            <span className="wgs">경도</span>
            {renderCoordinate(coordinates.lon, true)}
          </li>

          {/* 위도 */}
          <li className="divider">
            <span className="wgs">위도</span>
            {renderCoordinate(coordinates.lat, false)}
          </li>

          {/* 현재 시간 */}
          <li className="time-section">
            <span className={`time-badge ${timeFormat}`}>{timeLabel}</span>
            <span>{timeData.dateStr}({timeData.dayOfWeek})</span>
            <span>{timeData.timeStr}</span>
          </li>

          {/* 설정 버튼 */}
          <li className="settings-container" ref={settingsRef}>
            <button
              type="button"
              className={`set ${showSettings ? 'active' : ''}`}
              onClick={toggleSettings}
            >
              <span className="blind">설정</span>
            </button>

            {/* 설정 드롭다운 */}
            {showSettings && (
              <div className="settings-dropdown">
                <div className="settings-group">
                  <div className="settings-label">위경도 표기</div>
                  <div className="settings-options">
                    <button
                      type="button"
                      className={coordFormat === 'dms' ? 'active' : ''}
                      onClick={() => setCoordFormat('dms')}
                    >
                      도분초
                    </button>
                    <button
                      type="button"
                      className={coordFormat === 'decimal' ? 'active' : ''}
                      onClick={() => setCoordFormat('decimal')}
                    >
                      도
                    </button>
                  </div>
                </div>
                <div className="settings-group">
                  <div className="settings-label">시간 표기</div>
                  <div className="settings-options">
                    <button
                      type="button"
                      className={timeFormat === 'kst' ? 'active' : ''}
                      onClick={() => setTimeFormat('kst')}
                    >
                      KST
                    </button>
                    <button
                      type="button"
                      className={timeFormat === 'utc' ? 'active' : ''}
                      onClick={() => setTimeFormat('utc')}
                    >
                      UTC
                    </button>
                  </div>
                </div>
              </div>
            )}
          </li>

          {/* 선박 버튼 */}
          <li className="ship-mode-container">
            <button
              type="button"
              className={`ship ${mode === 'ship' ? 'active' : ''}`}
              onClick={setShipMode}
            >
              <span className="blind">선박</span>
            </button>

            {/* 추적 중인 함정 정보 표시 */}
            {mode === 'ship' && trackedShip && (
              <div className="tracked-ship-info">
                <span className="tracked-name">{trackedShip.shipName || trackedShip.originalTargetId}</span>
                <span className="tracked-radius">{radiusNM}NM</span>
              </div>
            )}

            {/* 함정 선택 드롭다운 */}
            <PatrolShipSelector />
          </li>
        </ul>
      </div>

      {/* 검색 박스 */}
      <div className="topSchBox" ref={searchContainerRef}>
        <div className="search-input-wrapper">
          <input
            type="text"
            className="tschInput"
            placeholder="선박 위치 검색"
            value={searchValue}
            onChange={handleSearchChange}
            onKeyDown={handleKeyDown}
            onFocus={() => setIsSearchFocused(true)}
          />
          {searchValue && (
            <button
              type="button"
              className="search-clear-btn"
              onClick={clearSearch}
              title="검색어 지우기"
            >
              ×
            </button>
          )}
        </div>

        {/* 검색 결과 목록 */}
        {isSearchFocused && searchValue && results.length > 0 && (
          <ul className="search-results">
            {results.map((result) => (
              <li
                key={result.featureId}
                className="search-result-item"
                onClick={() => handleResultClick(result)}
              >
                <div className="result-info">
                  <span className="result-name" title={result.shipName}>
                    {truncateString(result.shipName)}
                  </span>
                  <span className="result-id" title={isIntegrate ? result.targetId : result.originalTargetId}>
                    {truncateString(isIntegrate ? result.targetId : result.originalTargetId, 15)}
                  </span>
                </div>
                <div className="result-action">
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                    <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/>
                  </svg>
                </div>
              </li>
            ))}
          </ul>
        )}

        {/* 검색 안내 / 결과 없음 */}
        {isSearchFocused && searchValue && results.length === 0 && (
          <div className="search-no-results">
            {searchValue.length < 2 ? (
              '한글 2자 이상, 영문/숫자 3자 이상 입력'
            ) : (
              '검색 결과가 없습니다'
            )}
          </div>
        )}
      </div>
    </section>
  );
}
