import { create } from "zustand"; import { api } from "../lib/api.ts"; export type UserStatus = "online" | "idle" | "dnd" | "offline"; export interface User { id: string; username: string; display_name: string; email: string; avatar: string; bio: string; accent_color: string; status: UserStatus; status_text: string; created_at: string; banner_url?: string; tagline?: string; pronouns?: string; social_links?: { platform: string; url: string }[]; } export interface PublicProfile extends User { badges: { id: string; name: string; icon: string; description?: string; server_id?: string }[]; } export type BlockedUser = { id: string; username: string; created_at: string; }; export interface UpdateProfilePayload { avatar_url?: string; display_name?: string; bio?: string; accent_color?: string; status_text?: string; status?: UserStatus; banner_url?: string; tagline?: string; pronouns?: string; social_links?: { platform: string; url: string }[]; } interface AuthState { user: User | null; isAuthenticated: boolean; isLoading: boolean; error: string | null; login: (identifier: string, password: string) => Promise; register: ( email: string, username: string, password: string, displayName?: string, ) => Promise; logout: () => Promise; fetchMe: () => Promise; updateProfile: (data: UpdateProfilePayload) => Promise; changePassword: ( currentPassword: string, newPassword: string, ) => Promise; getPublicProfile: (userId: string) => Promise; listBlocks: () => Promise; blockUser: (userId: string) => Promise; unblockUser: (userId: string) => Promise; clearError: () => void; } export const useAuthStore = create((set) => ({ user: null, isAuthenticated: false, isLoading: false, error: null, login: async (identifier, password) => { set({ isLoading: true, error: null }); try { await api.post("/auth/login/password", { email: identifier, password, }); const user = await api.get("/auth/me"); set({ user, isAuthenticated: true, isLoading: false }); } catch (error) { set({ isLoading: false, error: error instanceof Error ? error.message : "Login failed", }); throw error; } }, register: async (email, username, password, displayName) => { set({ isLoading: true, error: null }); try { await api.post("/auth/register", { email, username, password, display_name: displayName || username, }); const user = await api.get("/auth/me"); set({ user, isAuthenticated: true, isLoading: false }); } catch (error) { set({ isLoading: false, error: error instanceof Error ? error.message : "Registration failed", }); throw error; } }, logout: async () => { set({ isLoading: true, error: null }); try { await api.post("/auth/logout"); set({ user: null, isAuthenticated: false, isLoading: false }); } catch (error) { set({ isLoading: false, error: error instanceof Error ? error.message : "Logout failed", }); throw error; } }, fetchMe: async () => { set({ isLoading: true, error: null }); try { const user = await api.get(`/auth/me?t=${Date.now()}`); set({ user, isAuthenticated: true, isLoading: false }); } catch (error) { set({ user: null, isAuthenticated: false, isLoading: false, error: error instanceof Error ? error.message : "Failed to fetch user", }); } }, updateProfile: async (data) => { set({ isLoading: true, error: null }); try { const user = await api.patch("/auth/me", data); set({ user, isLoading: false }); } catch (error) { set({ isLoading: false, error: error instanceof Error ? error.message : "Update failed", }); throw error; } }, changePassword: async (currentPassword, newPassword) => { set({ isLoading: true, error: null }); try { await api.put("/auth/me/password", { current_password: currentPassword, new_password: newPassword, }); set({ isLoading: false }); } catch (error) { set({ isLoading: false, error: error instanceof Error ? error.message : "Password change failed", }); throw error; } }, clearError: () => set({ error: null }), getPublicProfile: async (userId) => api.get(`/users/${userId}/profile`), listBlocks: async () => api.get('/users/me/blocks'), blockUser: async (userId) => { await api.post('/users/me/blocks', { user_id: userId }); }, unblockUser: async (userId) => { await api.delete(`/users/me/blocks/${userId}`); }, }));