import { useState, useCallback } from "react"; import { classifyError } from "@/lib/api/errorTypes"; import { isApiError, type RateLimitScope } from "@/lib/api/client"; type RateLimitState = { isRateLimited: boolean; remainingSeconds: number; canRetry: boolean; scope: RateLimitScope | null; }; export function useRateLimit() { const [rateLimitState, setRateLimitState] = useState({ isRateLimited: false, remainingSeconds: 0, canRetry: true, scope: null, }); const checkRateLimit = useCallback((error: unknown): boolean => { const errorInfo = classifyError(error); if (errorInfo.type === "RATE_LIMITED") { const scope = isApiError(error) ? error.rateLimitScope : null; const retryAfter = isApiError(error) && typeof error.retryAfter === "number" ? error.retryAfter : 30; setRateLimitState({ isRateLimited: true, remainingSeconds: retryAfter, canRetry: false, scope, }); // Start countdown let secondsLeft = retryAfter; const countdownInterval = setInterval(() => { secondsLeft -= 1; if (secondsLeft <= 0) { clearInterval(countdownInterval); setRateLimitState({ isRateLimited: false, remainingSeconds: 0, canRetry: true, scope: null, }); } else { setRateLimitState(prev => ({ ...prev, remainingSeconds: secondsLeft, })); } }, 1000); return true; } return false; }, []); const resetRateLimit = useCallback(() => { setRateLimitState({ isRateLimited: false, remainingSeconds: 0, canRetry: true, scope: null, }); }, []); const getRateLimitMessage = useCallback(() => { if (rateLimitState.isRateLimited) { return `You're moving fast. I'll be ready in ${rateLimitState.remainingSeconds} seconds.`; } return ""; }, [rateLimitState]); return { rateLimitState, checkRateLimit, resetRateLimit, getRateLimitMessage, }; }