import { useEffect, useRef, useState } from 'react'; import { useRouter } from 'next/navigation'; import { getCurrentVoyage, saveCurrentVoyage } from '@/shared/lib/store'; import { Voyage } from '@/shared/types'; const getVoyageFromStore = () => { const current = getCurrentVoyage(); if (!current || current.status !== 'in_progress') { return null; } return current; }; const getEndTime = (voyage: Voyage | null) => { if (!voyage) return 0; return voyage.startedAt + voyage.durationMinutes * 60 * 1000; }; const getInitialTimerSeconds = (voyage: Voyage | null) => { if (!voyage) return 0; if (voyage.durationMinutes === 0) { return Math.max(0, Math.floor((Date.now() - voyage.startedAt) / 1000)); } const endTime = getEndTime(voyage); if (!endTime) return 0; return Math.max(0, Math.ceil((endTime - Date.now()) / 1000)); }; const formatHHMMSS = (totalSeconds: number) => { const hours = Math.floor(totalSeconds / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; return `${hours.toString().padStart(2, '0')}:${minutes .toString() .padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; }; export function useFlightSession() { const router = useRouter(); const [voyage] = useState(() => getVoyageFromStore()); const [timeLeft, setTimeLeft] = useState(() => getInitialTimerSeconds(getVoyageFromStore()), ); const [isPaused, setIsPaused] = useState(false); const endTimeRef = useRef(getEndTime(getVoyageFromStore())); const pausedElapsedMsRef = useRef(0); const pausedAtMsRef = useRef(null); useEffect(() => { if (voyage) return; router.replace('/'); }, [voyage, router]); useEffect(() => { if (!voyage || isPaused) return; const interval = setInterval(() => { if (voyage.durationMinutes === 0) { const elapsedMs = Date.now() - voyage.startedAt - pausedElapsedMsRef.current; setTimeLeft(Math.max(0, Math.floor(elapsedMs / 1000))); return; } const diff = endTimeRef.current - Date.now(); if (diff <= 0) { setTimeLeft(0); clearInterval(interval); return; } setTimeLeft(Math.ceil(diff / 1000)); }, 1000); return () => clearInterval(interval); }, [voyage, isPaused]); const handlePauseToggle = () => { if (voyage?.durationMinutes === 0) { if (isPaused) { if (pausedAtMsRef.current !== null) { pausedElapsedMsRef.current += Date.now() - pausedAtMsRef.current; } pausedAtMsRef.current = null; setIsPaused(false); return; } pausedAtMsRef.current = Date.now(); setIsPaused(true); return; } if (isPaused) { endTimeRef.current = Date.now() + timeLeft * 1000; setIsPaused(false); return; } setIsPaused(true); }; const handleFinish = () => { if (!voyage) return null; const endedVoyage: Voyage = { ...voyage, endedAt: voyage.endedAt || Date.now(), }; saveCurrentVoyage(endedVoyage); return endedVoyage; }; const formatTime = (seconds: number) => formatHHMMSS(seconds); return { voyage, timeLeft, isCountdownCompleted: Boolean(voyage && voyage.durationMinutes > 0 && timeLeft === 0), isPaused, formattedTime: formatTime(timeLeft), handlePauseToggle, handleFinish, }; }