import { useCallback } from 'react'
import debounce from 'lodash.debounce'
import type { HookFetcher } from '@commerce/utils/types'
import useCartUpdateItem from '@commerce/cart/use-update-item'
import useCart from './use-cart'
import { cartFragment } from '@framework/api/fragments/cart'
import {
  AdjustOrderLineMutation,
  AdjustOrderLineMutationVariables,
  ErrorResult,
} from '@framework/schema'
import { CommerceError } from '@commerce/utils/errors'

export const adjustOrderLineMutation = /* GraphQL */ `
  mutation adjustOrderLine($orderLineId: ID!, $quantity: Int!) {
    adjustOrderLine(orderLineId: $orderLineId, quantity: $quantity) {
      __typename
      ...Cart
      ... on ErrorResult {
        errorCode
        message
      }
    }
  }
  ${cartFragment}
`
export const fetcher: HookFetcher<
  AdjustOrderLineMutation,
  AdjustOrderLineMutationVariables
> = (options, { orderLineId, quantity }, fetch) => {
  return fetch({
    ...options,
    query: adjustOrderLineMutation,
    variables: { orderLineId, quantity },
  })
}

function extendHook(customFetcher: typeof fetcher, cfg?: { wait?: number }) {
  const useUpdateItem = (item?: any) => {
    const { mutate } = useCart()
    const fn = useCartUpdateItem<
      AdjustOrderLineMutation,
      AdjustOrderLineMutationVariables
    >({}, customFetcher)

    return useCallback(
      debounce(async (input: any) => {
        const { adjustOrderLine } = await fn({
          orderLineId: item.id,
          quantity: input.quantity,
        })
        if (adjustOrderLine.__typename === 'Order') {
          await mutate({ adjustOrderLine }, false)
        } else {
          throw new CommerceError({
            message: (adjustOrderLine as ErrorResult).message,
          })
        }
        return { adjustOrderLine }
      }, cfg?.wait ?? 500),
      [fn, mutate]
    )
  }

  useUpdateItem.extend = extendHook

  return useUpdateItem
}

export default extendHook(fetcher)
