import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { useAuthToken } from "../hooks/use-root-data"; import { useEffect, useState } from "react"; import { createShoppingCartApi } from "~/utils/api-client-factory"; // Hook to get all carts export function useGetAllCarts() { const token = useAuthToken(); return useQuery({ queryKey: ["carts", "list"], queryFn: async () => { console.log("📥 Fetching cart list..."); try { const cartApi = createShoppingCartApi(token); const result = await cartApi.apiShoppingcartV1CartList(); return result; } catch (error) { console.error("❌ Error fetching carts:", error); return []; } }, // Run even without token for guest carts retry: 1, staleTime: 30 * 60 * 1000, // 30 seconds - balance between freshness and performance refetchOnWindowFocus: false, }); } // Hook to get cart count export function useGetCartCount() { const token = useAuthToken(); return useQuery({ queryKey: ["carts", "count"], queryFn: async () => { try { if (!token) return 0; const cartApi = createShoppingCartApi(token); const carts = await cartApi.apiShoppingcartV1CartList(); // Calculate total items across all carts return carts.reduce((total, cart) => { return total + (cart.items?.length || 0); }, 0); } catch (error) { console.error("Error getting cart count:", error); return 0; } }, enabled: !!token, // Only run if user is authenticated staleTime: 2 * 60 * 1000, // 2 minutes - cart count doesn't change often gcTime: 5 * 60 * 1000, // 5 minutes retry: 1, }); } // Hook to add item to cart export function useAddToCart() { const token = useAuthToken(); const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ variantId, quantity, }: { variantId: string; quantity: number; }) => { try { const cartApi = createShoppingCartApi(token); await cartApi.apiShoppingcartV1CartAddCreate({ data: { productVariantId: variantId, quantity: quantity, }, }); return true; } catch (error) { console.error("Failed to add item to cart:", error); return false; } }, onSuccess: async () => { // Invalidate and refetch cart queries immediately await Promise.all([ queryClient.invalidateQueries({ queryKey: ["carts", "list"], refetchType: "all", // Refetch all queries, not just active ones }), queryClient.invalidateQueries({ queryKey: ["carts", "count"], refetchType: "all", }), ]); }, onError: (error) => { console.error("Failed to add item to cart:", error); }, }); } // Hook to update cart item quantity export function useUpdateCartItemQuantity() { const token = useAuthToken(); const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ itemId, quantity, }: { itemId: string; quantity: number; }) => { try { const cartApi = createShoppingCartApi(token); await cartApi.apiShoppingcartV1CartEditPartialUpdate({ data: { itemId, quantity, }, }); return true; } catch (error) { console.error("Error updating cart item quantity:", error); return false; } }, onSuccess: async () => { // Invalidate and refetch all cart queries immediately await Promise.all([ queryClient.invalidateQueries({ queryKey: ["carts", "list"], refetchType: "all", }), queryClient.invalidateQueries({ queryKey: ["carts", "count"], refetchType: "all", }), queryClient.invalidateQueries({ queryKey: ["carts", "detail"], refetchType: "all", }), ]); }, }); } // Hook to remove item from cart export function useRemoveFromCart() { const token = useAuthToken(); const queryClient = useQueryClient(); return useMutation({ mutationFn: async (itemId: string) => { try { const cartApi = createShoppingCartApi(token); await cartApi.apiShoppingcartV1CartRemoveDelete({ itemId }); return true; } catch (error) { console.error("Error removing item from cart:", error); return false; } }, onSuccess: async () => { // Invalidate and refetch all cart queries immediately await Promise.all([ queryClient.invalidateQueries({ queryKey: ["carts", "list"], refetchType: "all", }), queryClient.invalidateQueries({ queryKey: ["carts", "count"], refetchType: "all", }), queryClient.invalidateQueries({ queryKey: ["carts", "detail"], refetchType: "all", }), ]); }, }); } // Hook to clear cart export function useClearCart() { const token = useAuthToken(); const queryClient = useQueryClient(); return useMutation({ mutationFn: async (cartId: string) => { try { const cartApi = createShoppingCartApi(token); await cartApi.apiShoppingcartV1CartClearCreate({ cartId }); return true; } catch (error) { console.error("Error clearing cart:", error); return false; } }, onSuccess: async () => { // Invalidate and refetch all cart queries immediately await Promise.all([ queryClient.invalidateQueries({ queryKey: ["carts", "list"], refetchType: "all", }), queryClient.invalidateQueries({ queryKey: ["carts", "count"], refetchType: "all", }), queryClient.invalidateQueries({ queryKey: ["carts", "detail"], refetchType: "all", }), ]); }, }); } // Hook to get details of a specific cart export function useGetCartDetails(cartId: string) { const token = useAuthToken(); return useQuery({ queryKey: ["carts", "detail", cartId], queryFn: async () => { try { const cartApi = createShoppingCartApi(token); return await cartApi.apiShoppingcartV1CartRead({ cartId }); } catch (error) { console.error(`Error fetching cart ${cartId}:`, error); return null; } }, enabled: !!cartId, // Only run if we have a cart ID retry: 1, staleTime: 30 * 60 * 1000, // 30 seconds - balance between freshness and performance refetchOnWindowFocus: false, }); } export const useCartCount = () => { const [count, setCount] = useState(0); const { data: cartCount, isLoading } = useGetCartCount(); // Update local state whenever the query data changes useEffect(() => { if (!isLoading && cartCount !== undefined) { setCount(cartCount); } }, [cartCount, isLoading]); return count; };