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 { normalizeCart } from '../lib/normalize' import type { RemoveCartItemBody, Cart, BigcommerceCart, LineItem, } from '../types' import useCart from './use-cart' const defaultOpts = { url: '/api/bigcommerce/cart', method: 'DELETE', } 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 }, fetch ) => { const data = await fetch({ ...defaultOpts, ...options, body: { itemId }, }) return normalizeCart(data) } export function extendHook(customFetcher: typeof fetcher) { const useRemoveItem = ( item?: T ) => { const { mutate } = 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({ itemId }) await mutate(data, false) return data } return useCallback(removeItem as RemoveItemFn, [fn, mutate]) } useRemoveItem.extend = extendHook return useRemoveItem } export default extendHook(fetcher)