"use client"; import { create } from "zustand"; import { calculateSplits, type Payment } from "@/lib/utils/expense"; import type { Group, User } from "@/server/db/schema"; export enum SplitTypeEnum { Fixed = "fixed", Percentage = "percentage", Equal = "equal", } export type SplitType = keyof typeof SplitTypeEnum; export const splitTypeKeys = Object.keys(SplitTypeEnum); interface ExpenseStore { amount: number; participants: User[]; groupBadges: Group[]; friendTarget?: string; splitType: SplitType; payments: Payment[]; splits: Record; setAmount: (amount: number) => void; addGroupBadges: (groupIds: Group[]) => void; removeGroupBadge: (groupIds: string[]) => void; addParticipants: (user: User[]) => void; removeParticipant: (userId: string) => void; setFriendTarget: (id?: string) => void; setSplitType: (type: SplitType) => void; setPayments: (payments: Array) => void; recalculateSplits: () => void; resetExpenseStore: () => void; } const defaultValues: Pick< ExpenseStore, | "amount" | "participants" | "friendTarget" | "splitType" | "payments" | "splits" | "groupBadges" > = { amount: 0, participants: [], groupBadges: [], friendTarget: undefined, splitType: "Equal", payments: [], splits: {}, }; export const useExpenseStore = create((set, get) => ({ ...defaultValues, setAmount: (amount) => set({ amount }), addParticipants: (newUsers) => { const { participants } = get(); const uniqueUsers = newUsers.filter( (user) => !participants.find((u) => u.id === user.id) ); set({ participants: [...participants, ...uniqueUsers] }); }, removeParticipant: (userId) => { const filtered = get().participants.filter((user) => user.id !== userId); set({ participants: filtered }); }, setFriendTarget: (id) => set({ friendTarget: id }), setSplitType: (type) => set({ splitType: type }), setPayments: (payments) => set({ payments }), recalculateSplits: () => { const { amount, participants, splitType } = get(); const splits = calculateSplits({ amount, users: participants.map((u) => u.id!), splitType, }); set({ splits }); }, addGroupBadges: (newGroups) => { const { groupBadges } = get(); const uniqueGroups = newGroups.filter( (group) => !groupBadges.find((g) => g.id === group.id) ); set({ groupBadges: [...groupBadges, ...uniqueGroups] }); }, removeGroupBadge: (groupIds) => set({ groupBadges: get().groupBadges.filter(({ id }) => !groupIds.includes(id)), }), resetExpenseStore: () => set(defaultValues), }));