import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import type { CartData as SharedCartData } from '@packages/shared' type CartType = 'regular' | 'flash' interface CartItem { id: number skuId: number quantity: number storeId: number | null addedAt: number slotId?: number | null deliveryDate?: string | null } type CartData = SharedCartData function getCartKey(cartType: CartType): string { return `local-cart-${cartType}` } function readCart(cartType: CartType): CartItem[] { try { const raw = localStorage.getItem(getCartKey(cartType)) return raw ? JSON.parse(raw) : [] } catch { return [] } } function writeCart(cartType: CartType, items: CartItem[]) { localStorage.setItem(getCartKey(cartType), JSON.stringify(items)) } // Build the exact shape useGetCart returns, so setQueryData matches the cache. function toCartData(items: CartItem[]): CartData { const totalItems = items.reduce((sum, item) => sum + item.quantity, 0) return { items, totalItems, totalAmount: 0 } } export function useGetCart(cartType: CartType = 'regular') { return useQuery({ queryKey: [getCartKey(cartType)], queryFn: () => toCartData(readCart(cartType)), }) } export function useAddToCart(cartType: CartType = 'regular') { const queryClient = useQueryClient() return useMutation({ mutationFn: async ({ skuId, quantity, storeId, slotId, deliveryDate, }: { skuId: number quantity: number storeId?: number | null slotId?: number | null deliveryDate?: string | null }) => { const items = readCart(cartType) const existing = items.find((i) => i.skuId === skuId) if (existing) { existing.quantity += quantity if (slotId) existing.slotId = slotId if (deliveryDate) existing.deliveryDate = deliveryDate } else { items.push({ id: Date.now(), skuId, quantity, storeId: storeId ?? null, addedAt: Date.now(), slotId: slotId ?? null, deliveryDate: deliveryDate ?? null, }) } writeCart(cartType, items) // Optimistically update the cache so the UI reflects the cart instantly, // before any refetch completes. queryClient.setQueryData([getCartKey(cartType)], toCartData(items)) }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: [getCartKey(cartType)] }) }, }) } export function useUpdateCartItem(cartType: CartType = 'regular') { const queryClient = useQueryClient() return useMutation({ mutationFn: async ({ skuId, quantity, slotId, deliveryDate, }: { skuId: number quantity: number slotId?: number | null deliveryDate?: string | null }) => { let items = readCart(cartType) const existing = items.find((i) => i.skuId === skuId) if (!existing) return if (quantity <= 0) { // Quantity hit 0 — remove the item from the cart entirely items = items.filter((i) => i.skuId !== skuId) } else { existing.quantity = quantity if (slotId !== undefined) existing.slotId = slotId if (deliveryDate !== undefined) existing.deliveryDate = deliveryDate } writeCart(cartType, items) queryClient.setQueryData([getCartKey(cartType)], toCartData(items)) }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: [getCartKey(cartType)] }) }, }) } export function useRemoveFromCart(cartType: CartType = 'regular') { const queryClient = useQueryClient() return useMutation({ mutationFn: async (skuId: number) => { let items = readCart(cartType) items = items.filter((i) => i.skuId !== skuId) writeCart(cartType, items) queryClient.setQueryData([getCartKey(cartType)], toCartData(items)) }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: [getCartKey(cartType)] }) }, }) } export function clearLocalCart(cartType: CartType = 'regular') { localStorage.removeItem(getCartKey(cartType)) }