'use client'
import { MutationFunction, MutationKey, useMutation, useQueryClient } from '@tanstack/react-query'
import { AxiosError } from 'axios'
import { useRef } from 'react'
import { toast } from 'react-toastify'
import { CustomUseMutationOptions } from '@/@core/types/api'
import { useTranslations } from 'next-intl'

export const useCustomMutation = <TVariable = any, TData = any, TError = TData>(
  mutationKey: MutationKey,
  mutationFn: MutationFunction<TData, TVariable>,
  options?: CustomUseMutationOptions<TData, AxiosError<TError>, TVariable>
) => {
  const t = useTranslations()
  const queryClient = useQueryClient()

  const toastId = useRef<any>(null)

  const notify = () => (toastId.current = toast.loading(t('COMMON.PROCESSING'), { autoClose: 2000 }))

  const update = (type: 'success' | 'error') => {
    let message = type === 'success' ? options?.promise?.message?.onSuccess : options?.promise?.message?.onError

    if (!options?.promise?.withoutTranslation && message) message = t(message)

    return (
      toastId &&
      toast.update(toastId.current, {
        render: message,
        type,
        autoClose: 3000,
        isLoading: false
      })
    )
  }

  const onMutate = async (variables: TVariable) => {
    if (!options?.withoutToastMessage && options?.toastMessageType === 'promise') notify()
    if (options?.onMutate) options.onMutate(variables)
  }

  const onSuccess = async (data: any, variables: any, context: unknown) => {
    // try {
    //   if (options?.onSuccess) await options.onSuccess(data, variables, context)

    //   if (options?.invalidateQueries) await queryClient.invalidateQueries({ queryKey: options.invalidateQueries })
    //   if (options?.refetchQueries)
    //     options.refetchQueries.map(rQ => queryClient.refetchQueries(rQ?.filters, rQ?.options))

    //   if (!options?.withoutToastMessage) {
    //     if (options?.toastMessageType === 'promise') {
    //       update('success')
    //     } else if (data?.messages?.length) {
    //       const messages: string[] = data?.messages
    //       if (messages?.length > 0) {
    //         messages?.map(message => toast.success(message))
    //       } else toast.success(messages)
    //     }
    //   }

    //   // queryClient.refetchQueries()
    // } catch (errors) {
    //   console.log('🚀 ~ file: useMutation.tsx:86 ~ onSuccess ~ errors:', errors)
    // }

    try {
      if (!options?.withoutToastMessage) {
        if (options?.toastMessageType === 'promise') {
          update('success')
        } else if (Array.isArray(data?.messages)) {
          const messages: string[] = data?.messages
          if (messages?.length > 0) {
            messages?.map(message => toast.success(message))
          }
        } else toast.success(data?.messages)
      }

      if (options?.onSuccess) await options.onSuccess(data, variables, context)

      if (options?.invalidateQueries) await queryClient.invalidateQueries({ queryKey: options.invalidateQueries })
      if (options?.refetchQueries)
        options.refetchQueries.map(rQ => queryClient.refetchQueries(rQ?.filters, rQ?.options))
    } catch (errors) {
      console.error('🚀 ~ onSuccess error:', errors)
    }
  }

  const onError = async (error: AxiosError<any>, variables: any, context: unknown): Promise<void> => {
    try {
      if (!options?.withoutToastMessage) {
        const errorData = error?.response?.data as any
        if (options?.toastMessageType === 'promise') {
          update('error')
        } else if (Array.isArray(errorData?.messages)) {
          const messages: string[] = errorData.messages
          if (messages?.length > 0) {
            messages?.map(message => toast.error(message))
          }
        } else if (errorData?.message) {
          toast.error(errorData.message)
        } else if (errorData?.messages) {
          toast.error(errorData.messages)
        }
      }
      if (options?.onError) await options.onError(error, variables, context)
    } catch (errors) {
      console.log('🚀 ~ file: useMutation.tsx:103 ~ errors:', errors)
    }
  }
  const mutation = useMutation<TData, AxiosError<TError>, TVariable>({
    mutationKey,
    mutationFn,
    ...options,
    onError,
    onSuccess,
    onMutate
  })

  return mutation
}
