import { createContext, useContext, useEffect, useState, useCallback, useMemo } from 'react' import type { User, Session, AuthError } from '@supabase/supabase-js' import { supabase } from '../lib/supabase' interface AuthState { user: User | null session: Session | null loading: boolean } interface AuthContextValue extends AuthState { signInWithEmail: (email: string, password: string) => Promise<{ error: AuthError | null }> signUpWithEmail: (email: string, password: string) => Promise<{ error: AuthError | null }> signInWithGoogle: () => Promise<{ error: AuthError | null }> signInWithDiscord: () => Promise<{ error: AuthError | null }> signOut: () => Promise } const AuthContext = createContext(null) export function AuthProvider({ children }: { children: React.ReactNode }) { const [state, setState] = useState({ user: null, session: null, loading: true, }) useEffect(() => { supabase.auth.getSession().then(({ data: { session } }) => { setState({ user: session?.user ?? null, session, loading: false }) }) const { data: { subscription }, } = supabase.auth.onAuthStateChange((_event, session) => { setState({ user: session?.user ?? null, session, loading: false }) }) return () => subscription.unsubscribe() }, []) const signInWithEmail = useCallback(async (email: string, password: string) => { const { error } = await supabase.auth.signInWithPassword({ email, password }) return { error } }, []) const signUpWithEmail = useCallback(async (email: string, password: string) => { const { error } = await supabase.auth.signUp({ email, password }) return { error } }, []) const signInWithGoogle = useCallback(async () => { const { error } = await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: `${window.location.origin}/auth/callback` }, }) return { error } }, []) const signInWithDiscord = useCallback(async () => { const { error } = await supabase.auth.signInWithOAuth({ provider: 'discord', options: { redirectTo: `${window.location.origin}/auth/callback` }, }) return { error } }, []) const signOut = useCallback(async () => { await supabase.auth.signOut() }, []) const value = useMemo( () => ({ ...state, signInWithEmail, signUpWithEmail, signInWithGoogle, signInWithDiscord, signOut, }), [state, signInWithEmail, signUpWithEmail, signInWithGoogle, signInWithDiscord, signOut] ) return {children} } export function useAuth() { const context = useContext(AuthContext) if (!context) { throw new Error('useAuth must be used within an AuthProvider') } return context }