import { useCallback, useEffect, useMemo, useState, type ReactNode, } from 'react'; import type { AuthResponse, User } from '../types'; import { api } from '../utils/api'; import { AuthContext } from './AuthContext'; const DEV_MOCK_USER: User = { id: 1, email: 'htlee@gcsc.co.kr', name: '김개발 (DEV)', avatarUrl: null, status: 'ACTIVE', isAdmin: true, roles: [{ id: 1, name: 'ADMIN', description: '관리자', urlPatterns: ['/**'], defaultGrant: false }], createdAt: new Date().toISOString(), lastLoginAt: new Date().toISOString(), }; function isDevMockSession(): boolean { return import.meta.env.DEV && localStorage.getItem('dev-user') === 'true'; } export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(() => isDevMockSession() ? DEV_MOCK_USER : null, ); const [token, setToken] = useState( () => localStorage.getItem('token'), ); const [initialized, setInitialized] = useState( () => isDevMockSession() || !localStorage.getItem('token'), ); const logout = useCallback(() => { const hadToken = !!localStorage.getItem('token') && !isDevMockSession(); localStorage.removeItem('token'); localStorage.removeItem('dev-user'); setToken(null); setUser(null); if (hadToken) { api.post('/auth/logout').catch(() => {}); } }, []); const devLogin = useCallback(() => { localStorage.setItem('dev-user', 'true'); localStorage.setItem('token', 'dev-mock-token'); setToken('dev-mock-token'); setUser(DEV_MOCK_USER); setInitialized(true); }, []); const login = useCallback(async (googleToken: string) => { const res = await api.post('/auth/google', { idToken: googleToken, }); localStorage.setItem('token', res.token); setToken(res.token); setUser(res.user); }, []); useEffect(() => { if (!token || isDevMockSession()) return; let cancelled = false; api .get('/auth/me') .then((data) => { if (!cancelled) setUser(data); }) .catch(() => { if (!cancelled) logout(); }) .finally(() => { if (!cancelled) setInitialized(true); }); return () => { cancelled = true; }; }, [token, logout]); const loading = !initialized; const value = useMemo( () => ({ user, token, loading, login, devLogin: import.meta.env.DEV ? devLogin : undefined, logout }), [user, token, loading, login, devLogin, logout], ); return {children}; }