import { useCallback } from 'react' import { HookFetcher } from '@commerce/utils/types' import { ValidationError } from '@commerce/utils/errors' import useCartRemoveItem, { RemoveItemInput as UseRemoveItemInput, } from '@commerce/cart/use-remove-item' import useCart from './use-cart' import type { Cart, LineItem, RemoveCartItemBody } from '@commerce/types' import { checkoutLineItemRemoveMutation } from '@framework/utils/mutations' import getCheckoutId from '@framework/utils/get-checkout-id' import { checkoutToCart } from './utils' const defaultOpts = { query: checkoutLineItemRemoveMutation, } export type RemoveItemFn = T extends LineItem ? (input?: RemoveItemInput) => Promise : (input: RemoveItemInput) => Promise export type RemoveItemInput = T extends LineItem ? Partial : UseRemoveItemInput export const fetcher: HookFetcher = async ( options, { itemId, checkoutId }, fetch ) => { const data = await fetch({ ...defaultOpts, ...options, variables: { lineItemIds: [itemId], checkoutId }, }) return checkoutToCart(data?.checkoutLineItemsRemove) } export function extendHook(customFetcher: typeof fetcher) { const useRemoveItem = ( item?: T ) => { const { mutate, data: cart } = useCart() const fn = useCartRemoveItem(defaultOpts, customFetcher) const removeItem: RemoveItemFn = async (input) => { const itemId = input?.id ?? item?.id if (!itemId) { throw new ValidationError({ message: 'Invalid input used for this operation', }) } const data = await fn({ checkoutId: getCheckoutId(cart?.id), itemId, }) await mutate(data, false) return data } return useCallback(removeItem as RemoveItemFn, [fn, mutate]) } useRemoveItem.extend = extendHook return useRemoveItem } export default extendHook(fetcher)