import { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode } from 'react'; import type { UserRecord } from '@/types/collections'; import { hydratePocketBaseAuth, isAuthenticated, pb } from '@/services/pocketbase'; type AuthContextValue = { user: UserRecord | null; loading: boolean; login: (email: string, password: string) => Promise; register: (params: { email: string; password: string; name: string }) => Promise; logout: () => void; }; const AuthContext = createContext(null); export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { let cancelled = false; void (async () => { await hydratePocketBaseAuth(); if (cancelled) return; setUser((pb.authStore.record as UserRecord | null) ?? null); setLoading(false); })(); return () => { cancelled = true; }; }, []); useEffect(() => { const unsub = pb.authStore.onChange(() => { setUser((pb.authStore.record as UserRecord | null) ?? null); }); return () => unsub(); }, []); const login = useCallback(async (email: string, password: string) => { await pb.collection('users').authWithPassword(email.trim(), password); setUser((pb.authStore.record as UserRecord | null) ?? null); }, []); const register = useCallback(async (params: { email: string; password: string; name: string }) => { await pb.collection('users').create({ email: params.email.trim(), password: params.password, passwordConfirm: params.password, name: params.name.trim(), emailVisibility: true, }); await pb.collection('users').authWithPassword(params.email.trim(), params.password); setUser((pb.authStore.record as UserRecord | null) ?? null); }, []); const logout = useCallback(() => { pb.authStore.clear(); setUser(null); }, []); const value = useMemo( () => ({ user, loading, login, register, logout, }), [user, loading, login, register, logout], ); return {children}; } export function useAuth(): AuthContextValue { const ctx = useContext(AuthContext); if (!ctx) throw new Error('useAuth must be used within AuthProvider'); return ctx; } export { isAuthenticated };