/**
 * 리플레이 타임라인 컨트롤
 * 원본: src/tracking/components/TrackingTimeline.tsx (TS → JS 전환)
 *
 * animationStore를 사용하는 재생 컨트롤
 * - 재생/일시정지/정지
 * - 배속 조절 (1x ~ 1000x)
 * - 프로그레스 바 (range slider)
 * - 드래그 가능한 헤더
 * - 항적표시 토글
 */
import { useCallback, useEffect, useRef, useState, useMemo } from 'react';
import useAnimationStore, { PlaybackState } from '../stores/animationStore';
import usePlaybackTrailStore from '../stores/playbackTrailStore';
import './ReplayTimeline.scss';

// 배속 옵션
const PLAYBACK_SPEED_OPTIONS = [1, 10, 50, 100, 500, 1000];

/**
 * 날짜 포맷팅 (YYYY-MM-DD HH:mm 형식)
 */
function formatDateRange(dateStr) {
  if (!dateStr) return '';
  try {
    const date = new Date(dateStr);
    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');
    return `${year}-${month}-${day} ${hours}:${minutes}`;
  } catch {
    return dateStr;
  }
}

/**
 * ms → 날짜시간 문자열 (YYYY-MM-DD HH:mm:ss)
 */
function formatDateTime(ms) {
  if (!ms || ms <= 0) return '--:--:--';
  const d = new Date(ms);
  const pad = (n) => String(n).padStart(2, '0');
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
}

/**
 * 리플레이 타임라인 컨트롤 컴포넌트
 */
export default function ReplayTimeline({ fromDate, toDate, onClose }) {
  // animationStore 상태
  const playbackState = useAnimationStore((s) => s.playbackState);
  const currentTime = useAnimationStore((s) => s.currentTime);
  const startTime = useAnimationStore((s) => s.startTime);
  const endTime = useAnimationStore((s) => s.endTime);
  const playbackSpeed = useAnimationStore((s) => s.playbackSpeed);

  // 액션
  const play = useAnimationStore((s) => s.play);
  const pause = useAnimationStore((s) => s.pause);
  const stop = useAnimationStore((s) => s.stop);
  const seekTo = useAnimationStore((s) => s.seekTo);
  const setPlaybackSpeed = useAnimationStore((s) => s.setPlaybackSpeed);

  const isPlaying = playbackState === PlaybackState.PLAYING;

  // 진행률
  const progress = useMemo(() => {
    if (endTime <= startTime || startTime <= 0) return 0;
    return ((currentTime - startTime) / (endTime - startTime)) * 100;
  }, [currentTime, startTime, endTime]);

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

  // 드래그 상태
  const [isDragging, setIsDragging] = useState(false);
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
  const containerRef = useRef(null);

  // 항적표시 상태 (playbackTrailStore와 동기화)
  const isTrailEnabled = usePlaybackTrailStore((s) => s.isEnabled);
  const setTrailEnabled = usePlaybackTrailStore((s) => s.setEnabled);

  // 외부 클릭 시 드롭다운 닫기
  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 handleMouseDown = useCallback((e) => {
    if (containerRef.current) {
      const rect = containerRef.current.getBoundingClientRect();
      setDragOffset({
        x: e.clientX - rect.left - position.x,
        y: e.clientY - rect.top - position.y,
      });
      setIsDragging(true);
    }
  }, [position]);

  useEffect(() => {
    const handleMouseMove = (e) => {
      if (isDragging && containerRef.current) {
        const parent = containerRef.current.parentElement;
        if (parent) {
          const parentRect = parent.getBoundingClientRect();
          const containerRect = containerRef.current.getBoundingClientRect();

          let newX = e.clientX - parentRect.left - dragOffset.x;
          let newY = e.clientY - parentRect.top - dragOffset.y;

          // 경계 제한
          newX = Math.max(0, Math.min(newX, parentRect.width - containerRect.width));
          newY = Math.max(0, Math.min(newY, parentRect.height - containerRect.height));

          setPosition({ x: newX, y: newY });
        }
      }
    };

    const handleMouseUp = () => {
      setIsDragging(false);
    };

    if (isDragging) {
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
    }

    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [isDragging, dragOffset]);

  // 재생/일시정지 토글
  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 handleTrailToggle = useCallback(() => {
    setTrailEnabled(!isTrailEnabled);
  }, [setTrailEnabled, isTrailEnabled]);

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

  // 데이터 유효성 확인
  const hasData = endTime > startTime && startTime > 0;

  // 날짜 범위 표시 텍스트
  const dateRangeText =
    fromDate && toDate ? `${formatDateRange(fromDate)} ~ ${formatDateRange(toDate)}` : '';

  return (
    <div
      ref={containerRef}
      className={`replay-timeline ${isPlaying ? 'playing' : ''} ${isDragging ? 'dragging' : ''}`}
      style={{
        transform: position.x !== 0 || position.y !== 0
          ? `translate(${position.x}px, ${position.y}px)`
          : undefined,
      }}
    >
      {/* 드래그 가능한 헤더 */}
      <div className="timeline-header" onMouseDown={handleMouseDown}>
        <div className="header-content">
          <span className="header-title">리플레이</span>
          {dateRangeText && <span className="header-date-range">{dateRangeText}</span>}
        </div>
        {onClose && (
          <button type="button" className="header-close-btn" onClick={onClose} title="닫기">
            ✕
          </button>
        )}
      </div>

      {/* 컨트롤 영역 */}
      <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={currentTime}
            onChange={handleSliderChange}
            disabled={!hasData}
            style={{ '--progress': `${progress}%` }}
          />
        </div>

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

        {/* 항적표시 토글 */}
        <label className="trail-toggle">
          <input
            type="checkbox"
            checked={isTrailEnabled}
            onChange={handleTrailToggle}
            disabled={!hasData}
          />
          <span>항적</span>
        </label>
      </div>
    </div>
  );
}
