"use client"; import { useState, useRef, useCallback, useEffect } from "react"; interface UseTimerOptions { initialSeconds: number; onTimeUp: () => void; autoStart?: boolean; } export function useTimer({ initialSeconds, onTimeUp, autoStart = false }: UseTimerOptions) { const [seconds, setSeconds] = useState(initialSeconds); const [isRunning, setIsRunning] = useState(autoStart); const intervalRef = useRef | null>(null); const onTimeUpRef = useRef(onTimeUp); useEffect(() => { onTimeUpRef.current = onTimeUp; }, [onTimeUp]); const stop = useCallback(() => { setIsRunning(false); if (intervalRef.current) { clearInterval(intervalRef.current); intervalRef.current = null; } }, []); const start = useCallback(() => { setIsRunning(true); }, []); const reset = useCallback((newSeconds?: number) => { stop(); setSeconds(newSeconds ?? initialSeconds); }, [stop, initialSeconds]); // Tick the timer — pure updater, no side effects useEffect(() => { if (!isRunning) return; intervalRef.current = setInterval(() => { setSeconds((prev) => { if (prev <= 1) return 0; return prev - 1; }); }, 1000); return () => { if (intervalRef.current) clearInterval(intervalRef.current); }; }, [isRunning, stop]); // Fire side effects when timer reaches 0 useEffect(() => { if (isRunning && seconds === 0) { const timer = setTimeout(() => { stop(); onTimeUpRef.current(); }, 0); return () => clearTimeout(timer); } }, [seconds, isRunning, stop]); return { seconds, isRunning, start, stop, reset }; }