import { createContext, useContext, useState, useCallback, useEffect } from 'react' import { api, API_BASE } from '../api' const AuthContext = createContext(null) const TOKEN_KEY = 'omnidiag_token' const USER_KEY = 'omnidiag_user' export function AuthProvider({ children }) { const [token, setToken] = useState(() => { const stored = localStorage.getItem(TOKEN_KEY) if (stored) api.setToken(stored) // sync api client on page reload return stored }) const [user, setUser] = useState(() => { try { return JSON.parse(localStorage.getItem(USER_KEY) || 'null') } catch { return null } }) const [loginError, setLoginError] = useState(null) const [loginLoading, setLoginLoading] = useState(false) // Verify stored token is still valid on mount useEffect(() => { if (!token) return fetch(`${API_BASE}/auth/me`, { headers: { Authorization: `Bearer ${token}` } }) .then(r => r.ok ? r.json() : Promise.reject()) .then(u => { setUser(u); localStorage.setItem(USER_KEY, JSON.stringify(u)) }) .catch(() => { setToken(null); setUser(null); localStorage.removeItem(TOKEN_KEY); localStorage.removeItem(USER_KEY) }) }, []) // eslint-disable-line react-hooks/exhaustive-deps const login = useCallback(async (email, password) => { setLoginError(null) setLoginLoading(true) try { const res = await fetch(`${API_BASE}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }), }) const data = await res.json() if (!res.ok) throw new Error(data?.error || data?.detail || 'Login failed') const accessToken = data.access_token setToken(accessToken) api.setToken(accessToken) // wire token into api client localStorage.setItem(TOKEN_KEY, accessToken) // Fetch user profile const meRes = await fetch(`${API_BASE}/auth/me`, { headers: { Authorization: `Bearer ${accessToken}` } }) const me = await meRes.json() setUser(me) localStorage.setItem(USER_KEY, JSON.stringify(me)) return true } catch (e) { setLoginError(e.message) return false } finally { setLoginLoading(false) } }, []) const logout = useCallback(() => { fetch(`${API_BASE}/auth/logout`, { method: 'POST', headers: { Authorization: `Bearer ${token}` }, }).catch(() => {}) setToken(null) setUser(null) api.setToken(null) localStorage.removeItem(TOKEN_KEY) localStorage.removeItem(USER_KEY) }, [token]) const isAdmin = user?.roles?.some(r => ['admin', 'super_admin'].includes(typeof r === 'string' ? r : r?.name)) ?? false return ( {children} ) } export function useAuth() { const ctx = useContext(AuthContext) if (!ctx) throw new Error('useAuth must be used inside AuthProvider') return ctx }