import { useState, useCallback, useRef, useEffect } from 'react'; import type { ReplayState } from '../types'; import { REPLAY_START, REPLAY_END } from '../data/sampleData'; const TICK_INTERVAL = 200; // ms between updates const TIME_STEP = 240_000; // 4 minutes of replay time per tick at 1x speed (same visual speed) export function useReplay() { const [state, setState] = useState({ isPlaying: false, currentTime: REPLAY_START, startTime: REPLAY_START, endTime: REPLAY_END, speed: 1, }); const intervalRef = useRef(null); const stop = useCallback(() => { if (intervalRef.current !== null) { clearInterval(intervalRef.current); intervalRef.current = null; } }, []); const play = useCallback(() => { setState(prev => ({ ...prev, isPlaying: true })); }, []); const pause = useCallback(() => { stop(); setState(prev => ({ ...prev, isPlaying: false })); }, [stop]); const seek = useCallback((time: number) => { setState(prev => ({ ...prev, currentTime: Math.max(prev.startTime, Math.min(prev.endTime, time)), })); }, []); const setSpeed = useCallback((speed: number) => { setState(prev => ({ ...prev, speed })); }, []); const reset = useCallback(() => { stop(); setState(prev => ({ ...prev, isPlaying: false, currentTime: prev.startTime, })); }, [stop]); const setRange = useCallback((start: number, end: number) => { stop(); setState(prev => ({ ...prev, isPlaying: false, startTime: start, endTime: end, currentTime: Math.max(start, Math.min(end, prev.currentTime)), })); }, [stop]); useEffect(() => { if (state.isPlaying) { stop(); intervalRef.current = window.setInterval(() => { setState(prev => { const next = prev.currentTime + TIME_STEP * prev.speed; if (next >= prev.endTime) { return { ...prev, currentTime: prev.endTime, isPlaying: false }; } return { ...prev, currentTime: next }; }); }, TICK_INTERVAL); } else { stop(); } return stop; }, [state.isPlaying, state.speed, stop]); return { state, play, pause, seek, setSpeed, reset, setRange }; }