import { createContext, useContext, useState, useEffect, useCallback, useMemo, useRef, } from 'react' import api, { ACTIVE_CLUB_STORAGE_KEY } from '../utils/api' import { activeClubMemberships } from '../utils/activeClub' import { clearCoachSessionStorage } from '../utils/trainingPlanUtils' const AuthContext = createContext(null) function syncStoredActiveClub(profile) { const clubs = activeClubMemberships(profile?.clubs) const ids = new Set(clubs.map((c) => String(c.id))) const eff = profile?.effective_club_id if (eff != null && eff !== '' && ids.has(String(eff))) { localStorage.setItem(ACTIVE_CLUB_STORAGE_KEY, String(eff)) return } const stored = localStorage.getItem(ACTIVE_CLUB_STORAGE_KEY) if (stored && ids.has(stored)) return const ac = profile?.active_club_id != null && profile.active_club_id !== '' ? String(profile.active_club_id) : '' if (ac && ids.has(ac)) { localStorage.setItem(ACTIVE_CLUB_STORAGE_KEY, ac) return } if (clubs.length >= 1) { localStorage.setItem(ACTIVE_CLUB_STORAGE_KEY, String(clubs[0].id)) return } try { localStorage.removeItem(ACTIVE_CLUB_STORAGE_KEY) } catch { /* ignore */ } } export function AuthProvider({ children }) { const [user, setUser] = useState(null) const [loading, setLoading] = useState(true) const userRef = useRef(null) useEffect(() => { userRef.current = user }, [user]) const checkAuth = useCallback(async () => { const token = localStorage.getItem('authToken') if (!token) { setLoading(false) return } try { const profile = await api.getCurrentProfile() syncStoredActiveClub(profile) setUser(profile) } catch (err) { console.error('Auth check failed:', err) localStorage.removeItem('authToken') } finally { setLoading(false) } }, []) useEffect(() => { checkAuth() }, [checkAuth]) const setActiveClub = useCallback(async (clubId) => { const cid = Number(clubId) const uid = userRef.current?.id if (!Number.isFinite(cid) || cid < 1 || !uid) return localStorage.setItem(ACTIVE_CLUB_STORAGE_KEY, String(cid)) setUser((prev) => prev?.id ? { ...prev, active_club_id: cid, effective_club_id: cid } : prev ) try { await api.updateProfile(uid, { active_club_id: cid }) const profile = await api.getCurrentProfile() syncStoredActiveClub(profile) setUser(profile) } catch (e) { console.error(e) try { const profile = await api.getCurrentProfile() syncStoredActiveClub(profile) setUser(profile) } catch { /* ignore */ } } }, []) /** Fallback, falls ohne checkAuth gesetzt wird (Legacy / Token-Injektion) */ const login = useCallback((payload) => { if (payload?.profile != null) { syncStoredActiveClub(payload.profile) setUser(payload.profile) return } const p = payload if (p?.profile_id != null || p?.id != null) { setUser({ id: p.profile_id ?? p.id, name: p.name ?? null, email: p.email ?? null, role: p.role ?? 'user', tier: p.tier ?? 'free', }) return } setUser(payload) }, []) const logout = useCallback(async () => { try { await api.logout() } catch { /* Session lokal trotzdem beenden */ } setUser(null) localStorage.removeItem('authToken') localStorage.removeItem(ACTIVE_CLUB_STORAGE_KEY) clearCoachSessionStorage() }, []) const value = useMemo( () => ({ user, isAuthenticated: !!user, loading, login, logout, checkAuth, setActiveClub, }), [user, loading, login, logout, checkAuth, setActiveClub], ) return ( {children} ) } export function useAuth() { const context = useContext(AuthContext) if (!context) { throw new Error('useAuth must be used within AuthProvider') } return context } export default AuthContext