import { useCallback, useEffect, useRef } from 'react'; import type { MutableRefObject } from 'react'; import { clearAuthToken, logoutSession, refreshSession, setAuthToken } from '../../lib/apiClient'; type AppStatus = string; type AppDispatch = (action: { type: string; [key: string]: unknown }) => void; type SetStatusMessage = (message: string, variant?: string) => void; interface UseAuthManagerArgs { token?: string | null; appStatus: AppStatus; appDispatch: AppDispatch; setStatusMessage: SetStatusMessage; } interface UseAuthManagerResult { tokenRef: MutableRefObject; refreshAccessToken: () => Promise; handleLogout: () => Promise; } const useAuthManager = ({ token, appStatus, appDispatch, setStatusMessage, }: UseAuthManagerArgs): UseAuthManagerResult => { const tokenRef = useRef(token); const initialRefreshAttemptedRef = useRef(Boolean(token)); const refreshAccessToken = useCallback(async (): Promise => { console.log('[Auth] Attempting to refresh access token…'); appDispatch({ type: 'TOKEN_REFRESH_START' }); try { const data = await refreshSession(); if (data?.access_token) { setAuthToken(data.access_token); appDispatch({ type: 'TOKEN_REFRESH_SUCCESS', token: data.access_token, tenant: data.tenant || null, }); console.log('[Auth] Access token refreshed at', new Date().toISOString()); return data.access_token; } throw new Error('Missing access token in refresh response'); } catch (error) { console.warn('[Auth] Failed to refresh access token', error); appDispatch({ type: 'TOKEN_REFRESH_FAILURE', error: (error as Error)?.message || null }); throw error; } }, [appDispatch]); useEffect(() => { tokenRef.current = token; }, [token]); useEffect(() => { if (!token && !initialRefreshAttemptedRef.current && appStatus === 'logged-out') { initialRefreshAttemptedRef.current = true; console.log('[Auth] Attempting refresh at startup'); refreshAccessToken().catch(() => {}); } }, [token, appStatus, refreshAccessToken]); const handleLogout = useCallback(async () => { try { await logoutSession(); } catch (error) { console.warn('[Auth] Failed to revoke refresh token during logout', error); } finally { clearAuthToken(); appDispatch({ type: 'LOGOUT' }); setStatusMessage('Logged out.', 'info'); } }, [appDispatch, setStatusMessage]); return { tokenRef, refreshAccessToken, handleLogout }; }; export default useAuthManager;