import { createContext, useContext, useState, useEffect, useCallback } from 'react' import type { ReactNode } from 'react' import { apiFetch, setToken, clearToken, isAuthenticated } from '../utils/api' export interface User { id: number email: string displayName: string role: 'user' | 'admin' } interface AuthContextValue { user: User | null loading: boolean needsSetup: boolean setUser: (user: User | null) => void login: (email: string, password: string) => Promise register: (email: string, password: string, displayName: string) => Promise logout: () => void refreshUser: () => Promise } const AuthContext = createContext(null) export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(null) const [loading, setLoading] = useState(true) const [needsSetup, setNeedsSetup] = useState(false) const refreshUser = useCallback(async () => { try { // Always check setup status first const setupStatus = await apiFetch<{ needsSetup: boolean }>('/api/setup/status') if (setupStatus.needsSetup) { setNeedsSetup(true) setUser(null) setLoading(false) return } setNeedsSetup(false) if (!isAuthenticated()) { setUser(null) setLoading(false) return } const data = await apiFetch<{ id: number; email: string; displayName: string; role: 'user' | 'admin' }>('/api/auth/me') setUser({ id: data.id, email: data.email, displayName: data.displayName, role: data.role ?? 'user' }) } catch { clearToken() setUser(null) } finally { setLoading(false) } }, []) useEffect(() => { void refreshUser() }, [refreshUser]) const login = useCallback(async (email: string, password: string) => { const data = await apiFetch<{ token: string; user: User }>('/api/auth/login', { method: 'POST', body: JSON.stringify({ email, password }), }) setToken(data.token) setUser({ ...data.user, role: data.user.role ?? 'user' }) }, []) const register = useCallback(async (email: string, password: string, displayName: string): Promise => { const data = await apiFetch<{ message: string }>('/api/auth/register', { method: 'POST', body: JSON.stringify({ email, password, displayName }), }) return data.message }, []) const logout = useCallback(() => { clearToken() setUser(null) }, []) return ( {children} ) } export function useAuth(): AuthContextValue { const ctx = useContext(AuthContext) if (!ctx) throw new Error('useAuth must be used within an AuthProvider') return ctx }