"use client"; import { create } from "zustand"; import { persist } from "zustand/middleware"; import { authService } from "../services/authService"; import api from "../services/api"; import { useCartStore } from "./cartStore"; import { usePetStore } from "./usePetStore"; export type UserRole = "User_Guest" | "User_PetOwner" | "User_Partner"; export interface Address { id: string; title: string; receptorName: string; phone: string; province: string; city: string; detail: string; zipCode: string; isDefault: boolean; } export interface Transaction { id: string; type: 'top_up' | 'purchase'; amount: number; date: string; status: 'success' | 'failed' | 'pending'; } interface UserProfile { firstName: string; lastName: string; email: string; mobile: string; walletBalance: number; charityDonationTotal: number; addresses: Address[]; transactions: Transaction[]; } interface UserStore { role: UserRole; isLoggedIn: boolean; profile: UserProfile; setRole: (role: UserRole) => void; setLoggedIn: (isLoggedIn: boolean) => void; updateProfile: (profile: Partial) => Promise; addAddress: (address: Address) => Promise; updateAddress: (id: string, address: Address) => Promise; deleteAddress: (id: string) => Promise; setDefaultAddress: (id: string) => Promise; topUpWallet: (amount: number) => Promise; logout: () => void; fetchProfile: () => Promise; } export const useUserStore = create()( persist( (set) => ({ role: "User_Guest", isLoggedIn: false, profile: { firstName: "", lastName: "", email: "", mobile: "", walletBalance: 0, charityDonationTotal: 0, addresses: [], transactions: [], }, setRole: (role) => set({ role }), setLoggedIn: (isLoggedIn) => set({ isLoggedIn }), updateProfile: async (updates) => { try { const profileData = await authService.updateProfile(updates); set((state) => ({ profile: { ...state.profile, firstName: profileData.firstName, lastName: profileData.lastName, email: profileData.email, mobile: profileData.mobile || "", } })); } catch (error) { console.error("Failed to update profile:", error); throw error; } }, addAddress: async (address) => { try { // Remove ID so backend generates UUID const { id, ...addressData } = address; await api.post('/users/addresses', addressData); await useUserStore.getState().fetchProfile(); } catch (error) { console.error("Failed to add address:", error); throw error; } }, updateAddress: async (id, updated) => { try { const { id: _, ...addressData } = updated; await api.patch(`/users/addresses/${id}`, addressData); await useUserStore.getState().fetchProfile(); } catch (error) { console.error("Failed to update address:", error); throw error; } }, deleteAddress: async (id) => { try { await api.delete(`/users/addresses/${id}`); await useUserStore.getState().fetchProfile(); } catch (error) { console.error("Failed to delete address:", error); throw error; } }, setDefaultAddress: async (id) => { try { await api.patch(`/users/addresses/${id}/default`); await useUserStore.getState().fetchProfile(); } catch (error) { console.error("Failed to set default address:", error); throw error; } }, topUpWallet: async (amount) => { try { await api.post('/users/wallet/top-up', { amount }); await useUserStore.getState().fetchProfile(); } catch (error) { console.error("Failed to top-up wallet:", error); throw error; } }, logout: () => { authService.logout(); set({ role: "User_Guest", isLoggedIn: false, profile: { firstName: "", lastName: "", email: "", mobile: "", walletBalance: 0, charityDonationTotal: 0, addresses: [], transactions: [] }}); }, fetchProfile: async () => { try { const profileData = await authService.getProfile(); set({ isLoggedIn: true, role: (profileData.role as UserRole) || "User_PetOwner", profile: { firstName: profileData.firstName, lastName: profileData.lastName, email: profileData.email, mobile: profileData.mobile || "", walletBalance: Number(profileData.walletBalance), charityDonationTotal: Number(profileData.charityDonationTotal), addresses: (profileData as any).addresses || [], transactions: (profileData as any).walletTransactions?.map((t: any) => ({ id: t.id, type: t.type === 'deposit' ? 'top_up' : 'purchase', amount: Number(t.amount), date: t.createdAt, status: t.status === 'completed' ? 'success' : t.status === 'failed' ? 'failed' : 'pending' })) || [] } }); // Sync orders list to CartStore if (profileData.orders) { useCartStore.getState().setOrders(profileData.orders); } // Sync pets list to PetStore if (profileData.pets) { usePetStore.getState().setPets(profileData.pets); } } catch (error) { console.error("Failed to fetch user profile:", error); authService.logout(); set({ isLoggedIn: false, role: "User_Guest" }); } }, }), { name: "canina-user" } ) );