/**
 * GearReplayController — 어구 그룹 24시간 궤적 재생 컨트롤러
 *
 * 맵 위에 absolute 포지셔닝으로 표시.
 * Zustand subscribe 패턴으로 DOM 직접 업데이트 → 재생 중 React re-render 없음.
 */
import { useEffect, useRef } from 'react';
import { Button } from '@shared/components/ui/button';
import { useGearReplayStore } from '@stores/gearReplayStore';
import { Play, Pause, X } from 'lucide-react';

interface GearReplayControllerProps {
  onClose: () => void;
}

const SPEED_OPTIONS = [1, 2, 5, 10] as const;
type SpeedOption = (typeof SPEED_OPTIONS)[number];

function formatEpochTime(epochMs: number): string {
  if (epochMs === 0) return '--:--';
  const d = new Date(epochMs);
  const MM = String(d.getMonth() + 1).padStart(2, '0');
  const dd = String(d.getDate()).padStart(2, '0');
  const hh = String(d.getHours()).padStart(2, '0');
  const mm = String(d.getMinutes()).padStart(2, '0');
  return `${MM}/${dd} ${hh}:${mm}`;
}

export function GearReplayController({ onClose }: GearReplayControllerProps) {
  const play = useGearReplayStore((s) => s.play);
  const pause = useGearReplayStore((s) => s.pause);
  const seek = useGearReplayStore((s) => s.seek);
  const setSpeed = useGearReplayStore((s) => s.setSpeed);
  const isPlaying = useGearReplayStore((s) => s.isPlaying);
  const playbackSpeed = useGearReplayStore((s) => s.playbackSpeed);
  const startTime = useGearReplayStore((s) => s.startTime);
  const endTime = useGearReplayStore((s) => s.endTime);
  const snapshotRanges = useGearReplayStore((s) => s.snapshotRanges);
  const dataStartTime = useGearReplayStore((s) => s.dataStartTime);
  const dataEndTime = useGearReplayStore((s) => s.dataEndTime);

  // DOM refs for direct updates — no React state during playback
  const progressBarRef = useRef<HTMLDivElement>(null);
  const timeLabelRef = useRef<HTMLSpanElement>(null);
  const trackRef = useRef<HTMLDivElement>(null);

  // Subscribe to currentTime changes and update DOM directly
  useEffect(() => {
    const unsubscribe = useGearReplayStore.subscribe(
      (s) => s.currentTime,
      (currentTime) => {
        const duration = endTime - startTime;
        const pct = duration > 0 ? ((currentTime - startTime) / duration) * 100 : 0;

        if (progressBarRef.current) {
          progressBarRef.current.style.width = `${Math.min(100, pct)}%`;
        }
        if (timeLabelRef.current) {
          timeLabelRef.current.textContent = formatEpochTime(currentTime);
        }
      },
    );
    return unsubscribe;
  }, [startTime, endTime]);

  // Handle click on track to seek
  const handleTrackClick = (e: React.MouseEvent<HTMLDivElement>) => {
    if (!trackRef.current) return;
    const rect = trackRef.current.getBoundingClientRect();
    const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
    seek(startTime + ratio * (endTime - startTime));
  };

  const handlePlayPause = () => {
    if (isPlaying) {
      pause();
    } else {
      play();
    }
  };

  const duration = endTime - startTime;
  const initialPct =
    duration > 0
      ? ((useGearReplayStore.getState().currentTime - startTime) / duration) * 100
      : 0;

  return (
    <div className="absolute bottom-16 left-1/2 -translate-x-1/2 z-[1001] w-full max-w-[520px] px-3">
      <div className="bg-background/95 backdrop-blur-sm border border-border rounded-lg px-3 py-2 shadow-lg flex items-center gap-2">
        {/* Play / Pause */}
        <Button
          type="button"
          variant="ghost"
          size="sm"
          aria-label={isPlaying ? '일시정지' : '재생'}
          onClick={handlePlayPause}
          className="shrink-0 p-1"
          icon={
            isPlaying ? (
              <Pause className="w-4 h-4 text-heading" />
            ) : (
              <Play className="w-4 h-4 text-heading" />
            )
          }
        />

        {/* Speed selector */}
        <div className="flex items-center gap-1 shrink-0">
          {SPEED_OPTIONS.map((s) => (
            <button
              key={s}
              type="button"
              onClick={() => setSpeed(s)}
              className={[
                'text-xs px-1.5 py-0.5 rounded font-mono transition-colors',
                playbackSpeed === s
                  ? 'bg-primary text-on-vivid font-bold'
                  : 'text-hint hover:text-label hover:bg-surface-raised',
              ].join(' ')}
            >
              {s}x
            </button>
          ))}
        </div>

        {/* Start time */}
        <span className="text-[9px] font-mono text-hint shrink-0">{formatEpochTime(startTime)}</span>

        {/* Progress track */}
        <div
          ref={trackRef}
          className="flex-1 h-2 bg-surface-raised rounded-full cursor-pointer relative overflow-hidden min-w-[80px]"
          onClick={handleTrackClick}
          role="slider"
          aria-label="재생 위치"
          aria-valuemin={0}
          aria-valuemax={100}
          aria-valuenow={Math.round(initialPct)}
        >
          {/* 스냅샷 틱마크 */}
          {snapshotRanges.map((r, i) => (
            <div
              key={i}
              className="absolute top-0 bottom-0 w-px bg-amber-400/50"
              style={{ left: `${r * 100}%` }}
            />
          ))}
          <div
            ref={progressBarRef}
            className="absolute inset-y-0 left-0 bg-primary rounded-full transition-none"
            style={{ width: `${Math.min(100, Math.max(0, initialPct))}%` }}
          />
        </div>

        {/* End time */}
        <span className="text-[9px] font-mono text-hint shrink-0">{formatEpochTime(endTime)}</span>

        {/* Current time label */}
        <span
          ref={timeLabelRef}
          className="text-[10px] font-mono text-heading shrink-0 w-[75px] text-center font-bold"
        >
          {formatEpochTime(useGearReplayStore.getState().currentTime)}
        </span>

        {/* Close */}
        <button
          type="button"
          aria-label="재생 닫기"
          onClick={onClose}
          className="shrink-0 p-1 hover:bg-surface-raised rounded"
        >
          <X className="w-3.5 h-3.5 text-hint" />
        </button>
      </div>
    </div>
  );
}
