import { useQuery } from "@tanstack/react-query"; import type { Invoice, InvoiceList, InvoiceSsoLink, Subscription, PaymentMethodList, PaymentGatewayList, InvoicePaymentLink, } from "@customer-portal/shared"; import { useAuthStore } from "@/lib/auth/store"; import { authenticatedApi } from "@/lib/api"; interface UseInvoicesOptions { page?: number; limit?: number; status?: string; } export function useInvoices(options: UseInvoicesOptions = {}) { const { page = 1, limit = 10, status } = options; const { token, isAuthenticated } = useAuthStore(); return useQuery({ queryKey: ["invoices", page, limit, status], queryFn: async () => { if (!token) { throw new Error("Authentication required"); } const params = new URLSearchParams({ page: page.toString(), limit: limit.toString(), ...(status && { status }), }); return authenticatedApi.get(`/invoices?${params}`); }, staleTime: 60 * 1000, // 1 minute gcTime: 5 * 60 * 1000, // 5 minutes enabled: isAuthenticated && !!token, // Only run when authenticated }); } export function useInvoice(invoiceId: number) { const { token, isAuthenticated } = useAuthStore(); return useQuery({ queryKey: ["invoice", invoiceId], queryFn: async () => { if (!token) { throw new Error("Authentication required"); } return authenticatedApi.get(`/invoices/${invoiceId}`); }, staleTime: 60 * 1000, // 1 minute gcTime: 5 * 60 * 1000, // 5 minutes enabled: isAuthenticated && !!token, // Only run when authenticated }); } export function useInvoiceSubscriptions(invoiceId: number) { const { token, isAuthenticated } = useAuthStore(); return useQuery({ queryKey: ["invoice-subscriptions", invoiceId], queryFn: async () => { if (!token) { throw new Error("Authentication required"); } return authenticatedApi.get(`/invoices/${invoiceId}/subscriptions`); }, staleTime: 60 * 1000, // 1 minute gcTime: 5 * 60 * 1000, // 5 minutes enabled: isAuthenticated && !!token && !!invoiceId, // Only run when authenticated and invoiceId is valid }); } export async function createInvoiceSsoLink( invoiceId: number, target: "view" | "download" | "pay" = "view" ): Promise { const params = new URLSearchParams(); if (target !== "view") params.append("target", target); return authenticatedApi.post( `/invoices/${invoiceId}/sso-link${params.toString() ? `?${params.toString()}` : ""}` ); } export function usePaymentMethods() { const { token, isAuthenticated } = useAuthStore(); return useQuery({ queryKey: ["paymentMethods"], queryFn: async () => { if (!token) { throw new Error("Authentication required"); } return authenticatedApi.get(`/invoices/payment-methods`); }, staleTime: 1 * 60 * 1000, // Reduced to 1 minute for better refresh gcTime: 5 * 60 * 1000, // Reduced to 5 minutes enabled: isAuthenticated && !!token, retry: 3, // Retry failed requests retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000), // Exponential backoff }); } export function usePaymentGateways() { const { token, isAuthenticated } = useAuthStore(); return useQuery({ queryKey: ["paymentGateways"], queryFn: async () => { if (!token) { throw new Error("Authentication required"); } return authenticatedApi.get(`/invoices/payment-gateways`); }, staleTime: 60 * 60 * 1000, // 1 hour gcTime: 2 * 60 * 60 * 1000, // 2 hours enabled: isAuthenticated && !!token, }); } export async function createInvoicePaymentLink( invoiceId: number, paymentMethodId?: number, gatewayName?: string ): Promise { const params = new URLSearchParams(); if (paymentMethodId) params.append("paymentMethodId", paymentMethodId.toString()); if (gatewayName) params.append("gatewayName", gatewayName); return authenticatedApi.post( `/invoices/${invoiceId}/payment-link${params.toString() ? `?${params.toString()}` : ""}` ); }