/**
 * 항적조회 전용 타임라인 컨트롤
 *
 * TrackQueryViewer와 함께 사용하는 재생 컨트롤
 * - 재생/일시정지/정지
 * - 배속 조절 (1x ~ 1000x)
 * - 반복 재생
 */
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useTrackQueryAnimationStore, PLAYBACK_SPEED_OPTIONS } from '../stores/trackQueryAnimationStore';
import { useTrackQueryStore } from '../stores/trackQueryStore';
import './TrackQueryTimeline.scss';

/**
 * 항적조회 타임라인 컨트롤 컴포넌트
 *
 * @param {Object} props
 * @param {number} props.startTime 데이터 시작 시간
 * @param {number} props.endTime 데이터 종료 시간
 * @param {boolean} [props.compact] 컴팩트 모드
 */
export const TrackQueryTimeline = ({ startTime, endTime, compact = false }) => {
  // 애니메이션 스토어
  const isPlaying = useTrackQueryAnimationStore(state => state.isPlaying);
  const animationCurrentTime = useTrackQueryAnimationStore(state => state.currentTime);
  const playbackSpeed = useTrackQueryAnimationStore(state => state.playbackSpeed);
  const loop = useTrackQueryAnimationStore(state => state.loop);
  const loopStart = useTrackQueryAnimationStore(state => state.loopStart);
  const loopEnd = useTrackQueryAnimationStore(state => state.loopEnd);
  const play = useTrackQueryAnimationStore(state => state.play);
  const pause = useTrackQueryAnimationStore(state => state.pause);
  const stop = useTrackQueryAnimationStore(state => state.stop);
  const setAnimationCurrentTime = useTrackQueryAnimationStore(state => state.setCurrentTime);
  const setPlaybackSpeed = useTrackQueryAnimationStore(state => state.setPlaybackSpeed);
  const toggleLoop = useTrackQueryAnimationStore(state => state.toggleLoop);
  const setLoopSection = useTrackQueryAnimationStore(state => state.setLoopSection);
  const setTimeRange = useTrackQueryAnimationStore(state => state.setTimeRange);
  const getProgress = useTrackQueryAnimationStore(state => state.getProgress);
  const getLoopProgress = useTrackQueryAnimationStore(state => state.getLoopProgress);

  // 항적조회 스토어 (시간 동기화용)
  const setProgressByRatio = useTrackQueryStore(state => state.setProgressByRatio);

  // 배속 드롭다운 상태
  const [showSpeedMenu, setShowSpeedMenu] = useState(false);
  const speedMenuRef = useRef(null);
  const sliderContainerRef = useRef(null);

  // 구간반복 마커 드래그 상태
  const [draggingMarker, setDraggingMarker] = useState(null);

  // 시간 범위 설정
  useEffect(() => {
    if (startTime > 0 && endTime > startTime) {
      setTimeRange(startTime, endTime);
    }
  }, [startTime, endTime, setTimeRange]);

  // 스토어 동기화 쓰로틀링용 ref (200ms = 5fps, 배치 렌더러와 동기화)
  const lastSyncTimeRef = useRef(0);
  const wasPlayingRef = useRef(false);
  const SYNC_THROTTLE_MS = 200;

  // 애니메이션 시간 → 항적 스토어 시간 동기화 (쓰로틀링 적용)
  useEffect(() => {
    if (isPlaying && animationCurrentTime >= startTime && animationCurrentTime <= endTime) {
      const now = performance.now();
      if (now - lastSyncTimeRef.current >= SYNC_THROTTLE_MS) {
        lastSyncTimeRef.current = now;
        const ratio = (animationCurrentTime - startTime) / (endTime - startTime);
        setProgressByRatio(ratio);
      }
      wasPlayingRef.current = true;
    } else if (wasPlayingRef.current && !isPlaying) {
      wasPlayingRef.current = false;
      const ratio = (animationCurrentTime - startTime) / (endTime - startTime);
      setProgressByRatio(Math.max(0, Math.min(1, ratio)));
    }
  }, [animationCurrentTime, isPlaying, startTime, endTime, setProgressByRatio]);

  // 외부 클릭 시 드롭다운 닫기
  useEffect(() => {
    const handleClickOutside = (event) => {
      if (speedMenuRef.current && !speedMenuRef.current.contains(event.target)) {
        setShowSpeedMenu(false);
      }
    };

    if (showSpeedMenu) {
      document.addEventListener('mousedown', handleClickOutside);
    }

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

  // 재생/일시정지 토글
  const handlePlayPause = useCallback(() => {
    if (isPlaying) {
      pause();
    } else {
      play();
    }
  }, [isPlaying, play, pause]);

  // 정지
  const handleStop = useCallback(() => {
    stop();
  }, [stop]);

  // 배속 변경
  const handleSpeedChange = useCallback(
    (speed) => {
      setPlaybackSpeed(speed);
      setShowSpeedMenu(false);
    },
    [setPlaybackSpeed],
  );

  // 슬라이더로 시간 변경
  const handleSliderChange = useCallback(
    (e) => {
      const newTime = parseFloat(e.target.value);
      setAnimationCurrentTime(newTime);
      const ratio = (newTime - startTime) / (endTime - startTime);
      setProgressByRatio(ratio);
    },
    [setAnimationCurrentTime, startTime, endTime, setProgressByRatio],
  );

  // 반복 토글
  const handleLoopToggle = useCallback(() => {
    toggleLoop();
  }, [toggleLoop]);

  // 구간 마커 드래그 시작
  const handleMarkerMouseDown = useCallback(
    (marker) => (e) => {
      if (isPlaying) return;
      e.preventDefault();
      e.stopPropagation();
      setDraggingMarker(marker);
    },
    [isPlaying],
  );

  // 구간 마커 드래그 중
  useEffect(() => {
    if (!draggingMarker || !sliderContainerRef.current) return;

    const handleMouseMove = (e) => {
      const rect = sliderContainerRef.current.getBoundingClientRect();
      const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
      const newTime = startTime + ratio * (endTime - startTime);

      if (draggingMarker === 'start') {
        const maxStart = loopEnd - (endTime - startTime) * 0.01;
        setLoopSection(Math.min(newTime, maxStart), loopEnd);
      } else {
        const minEnd = loopStart + (endTime - startTime) * 0.01;
        setLoopSection(loopStart, Math.max(newTime, minEnd));
      }
    };

    const handleMouseUp = () => {
      setDraggingMarker(null);
    };

    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);

    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [draggingMarker, startTime, endTime, loopStart, loopEnd, setLoopSection]);

  // 데이터 유효성 확인
  const hasData = endTime > startTime && startTime > 0;
  const progress = getProgress();
  const loopProgress = getLoopProgress();

  // 시간 포맷팅 (날짜 + 시간) - YYYY-MM-DD HH:mm:ss
  const formatTime = (timestamp) => {
    if (!timestamp) return '---------- --:--:--';
    const date = new Date(timestamp);
    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');
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  };

  return (
    <div className={`track-query-timeline ${compact ? 'compact' : ''} ${isPlaying ? 'playing' : ''}`}>
      <div className="timeline-controls">
        {/* 배속 선택 */}
        <div className="speed-selector" ref={speedMenuRef}>
          <button
            type="button"
            className="speed-btn"
            onClick={() => setShowSpeedMenu(!showSpeedMenu)}
            disabled={!hasData}
          >
            {playbackSpeed}x
          </button>
          {showSpeedMenu && (
            <div className="speed-menu">
              {PLAYBACK_SPEED_OPTIONS.map(speed => (
                <button
                  key={speed}
                  type="button"
                  className={`speed-option ${playbackSpeed === speed ? 'active' : ''}`}
                  onClick={() => handleSpeedChange(speed)}
                >
                  {speed}x
                </button>
              ))}
            </div>
          )}
        </div>

        {/* 재생/일시정지 버튼 */}
        <button
          type="button"
          className={`control-btn play-btn ${isPlaying ? 'playing' : ''}`}
          onClick={handlePlayPause}
          disabled={!hasData}
          title={isPlaying ? '일시정지' : '재생'}
        >
          {isPlaying ? '❚❚' : '▶'}
        </button>

        {/* 정지 버튼 */}
        <button type="button" className="control-btn stop-btn" onClick={handleStop} disabled={!hasData} title="정지">
          ■
        </button>

        {/* 슬라이더 */}
        <div className="timeline-slider-container" ref={sliderContainerRef}>
          <input
            type="range"
            className="timeline-slider"
            min={startTime}
            max={endTime}
            step={(endTime - startTime) / 1000}
            value={animationCurrentTime}
            onChange={handleSliderChange}
            disabled={!hasData}
          />
          <div className="slider-progress" style={{ width: `${progress}%` }} />

          {/* 구간반복 UI (반복 체크 시에만 표시) */}
          {loop && hasData && (
            <>
              {/* 구간반복 범위 하이라이트 */}
              <div
                className="loop-section-highlight"
                style={{
                  left: `${loopProgress.start}%`,
                  width: `${loopProgress.end - loopProgress.start}%`,
                }}
              />

              {/* 시작점 마커 (A) */}
              <div
                className={`loop-marker loop-marker-start ${draggingMarker === 'start' ? 'dragging' : ''} ${
                  isPlaying ? 'disabled' : ''
                }`}
                style={{ left: `${loopProgress.start}%` }}
                onMouseDown={handleMarkerMouseDown('start')}
                title={`반복 시작: ${formatTime(loopStart)}`}
              >
                <span className="marker-label">A</span>
              </div>

              {/* 종료점 마커 (B) */}
              <div
                className={`loop-marker loop-marker-end ${draggingMarker === 'end' ? 'dragging' : ''} ${
                  isPlaying ? 'disabled' : ''
                }`}
                style={{ left: `${loopProgress.end}%` }}
                onMouseDown={handleMarkerMouseDown('end')}
                title={`반복 종료: ${formatTime(loopEnd)}`}
              >
                <span className="marker-label">B</span>
              </div>
            </>
          )}
        </div>

        {/* 현재 시간 */}
        <span className="current-time-display">{hasData ? formatTime(animationCurrentTime) : '--:--:--'}</span>

        {/* 반복 토글 */}
        <label className="loop-toggle">
          <input type="checkbox" checked={loop} onChange={handleLoopToggle} disabled={!hasData} />
          <span>반복</span>
        </label>
      </div>
    </div>
  );
};

export default TrackQueryTimeline;
