import { useMutation, useQueryClient } from "@tanstack/react-query"; import { apiClient, ApiErrorCode, apiErrorCode, isApiErrorCode, } from "@/shared/api"; import type { CreateBankCard, CreateBankOperation, CreateExpenseCategory, UpdateBankCard, UpdateBankOperation, UpdateExpenseCategory, } from "./types"; async function mutationData( request: Promise<{ data?: T; error?: unknown }>, ) { const { data, error } = await request; // eslint-disable-next-line @typescript-eslint/only-throw-error -- Preserve generated ProblemDetails for apiErrorCode and field-error consumers. if (error) throw error; return data; } function useBankMutationOptions() { const queryClient = useQueryClient(); const invalidate = () => queryClient.invalidateQueries({ predicate: ({ queryKey }) => { const [method, path] = queryKey; return ( method === "get" && typeof path === "string" && (path === "/api/v1/bank-cards" || path.startsWith("/api/v1/bank-cards/")) ); }, }); return { onError: (error: unknown) => { const errorCode = apiErrorCode(error); return [ ApiErrorCode.BankDependentRefunds, ApiErrorCode.BankIntentConflict, ApiErrorCode.BankRefundLimit, ApiErrorCode.BankVersionConflict, ApiErrorCode.BankWriteConflict, ].some(code => isApiErrorCode(errorCode, code)) ? invalidate() : undefined; }, onSuccess: invalidate, retry: false, } as const; } function useCreateBankCard() { const options = useBankMutationOptions(); return useMutation({ ...options, mutationFn: (body: CreateBankCard) => mutationData(apiClient.POST("/api/v1/bank-cards", { body })), }); } function useCreateBankOperation() { const options = useBankMutationOptions(); return useMutation({ ...options, mutationFn: (body: CreateBankOperation) => mutationData(apiClient.POST("/api/v1/bank-cards/operations", { body })), }); } function useCreateExpenseCategory() { const options = useBankMutationOptions(); return useMutation({ ...options, mutationFn: (body: CreateExpenseCategory) => mutationData(apiClient.POST("/api/v1/bank-cards/categories", { body })), }); } function useDeleteBankOperation() { const options = useBankMutationOptions(); return useMutation({ ...options, mutationFn: ({ id, version }: { id: string; version: number }) => mutationData( apiClient.DELETE("/api/v1/bank-cards/operations/{id}", { params: { path: { id }, query: { version } }, }), ), }); } function useUpdateBankCard() { const options = useBankMutationOptions(); return useMutation({ ...options, mutationFn: ({ body, id }: { body: UpdateBankCard; id: string }) => mutationData( apiClient.PATCH("/api/v1/bank-cards/{id}", { body, params: { path: { id } }, }), ), }); } function useUpdateBankOperation() { const options = useBankMutationOptions(); return useMutation({ ...options, mutationFn: ({ body, id }: { body: UpdateBankOperation; id: string }) => mutationData( apiClient.PATCH("/api/v1/bank-cards/operations/{id}", { body, params: { path: { id } }, }), ), }); } function useUpdateExpenseCategory() { const options = useBankMutationOptions(); return useMutation({ ...options, mutationFn: ({ body, id }: { body: UpdateExpenseCategory; id: string }) => mutationData( apiClient.PATCH("/api/v1/bank-cards/categories/{id}", { body, params: { path: { id } }, }), ), }); } export { useCreateBankCard, useCreateBankOperation, useCreateExpenseCategory, useDeleteBankOperation, useUpdateBankCard, useUpdateBankOperation, useUpdateExpenseCategory, };