import {
  DEFAULT_REQUEST_ERROR_CODE,
  DEFAULT_REQUEST_ERROR_MSG,
  ERROR_STATUS,
  NETWORK_ERROR_CODE,
  NETWORK_ERROR_MSG,
  REQUEST_TIMEOUT_CODE,
  REQUEST_TIMEOUT_MSG,
} from './service'
import type { BackendServiceResult, RequestServiceError } from './types'
import { showErrorMsg } from '@/utils/toast'
import type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
import service from './index'
import { useUserStore } from '@/stores/user'
import { push } from 'notivue'
import { generateLoginKey } from '@/api'
/**
 * 后端逻辑code报错处理
 * @param backendServiceResult 后端传来错误信息
 */
export function handleBackendError<T>(backendServiceResult: BackendServiceResult<T>) {
  const error: RequestServiceError = {
    type: 'backend',
    code: backendServiceResult.code || DEFAULT_REQUEST_ERROR_CODE,
    msg: backendServiceResult.message,
  }
  showErrorMsg(error)
  return Promise.reject(backendServiceResult)
}

/**
 * 处理请求成功后错误
 */
export function handleResponseError(response: AxiosResponse) {
  const error: RequestServiceError = {
    type: 'axios',
    code: DEFAULT_REQUEST_ERROR_CODE,
    msg: DEFAULT_REQUEST_ERROR_MSG,
  }

  if (!window.navigator.onLine) {
    // 网路错误
    Object.assign(error, { code: NETWORK_ERROR_CODE, msg: NETWORK_ERROR_MSG })
  } else {
    // 请求成功的状态码非200的错误
    const errorCode: ErrorStatus = response.status as ErrorStatus
    const msg = ERROR_STATUS[errorCode] || DEFAULT_REQUEST_ERROR_MSG
    Object.assign(error, { type: 'backend', code: errorCode, msg })
  }
  showErrorMsg(error)

  return Promise.reject(response)
}

/**
 * 处理请求失败
 */
type ErrorStatus = keyof typeof ERROR_STATUS
export function handleRequestError<T>(axiosError: AxiosError<BackendServiceResult<T>>) {
  const error: RequestServiceError = {
    type: 'axios',
    code: DEFAULT_REQUEST_ERROR_CODE,
    msg: DEFAULT_REQUEST_ERROR_MSG,
  }
  // 网络错误
  if (!window.navigator.onLine || axiosError.message === 'Network Error') {
    Object.assign(error, { code: NETWORK_ERROR_CODE, msg: NETWORK_ERROR_MSG })
  }
  // 请求超时
  else if (axiosError.code === REQUEST_TIMEOUT_CODE && axiosError.message.includes('timeout')) {
    /** 超时错误 */
    Object.assign(error, { code: REQUEST_TIMEOUT_CODE, msg: REQUEST_TIMEOUT_MSG })
  }
  // 请求出错,如404， 403
  else {
    const errorCode: ErrorStatus = axiosError.response?.status as ErrorStatus
    const msg =
      axiosError.response?.data.message || ERROR_STATUS[errorCode] || DEFAULT_REQUEST_ERROR_MSG
    Object.assign(error, { code: errorCode || DEFAULT_REQUEST_ERROR_CODE, msg })
    // 敏感词
    if (axiosError.response?.data.code === 501) {
      const message = axiosError.response?.data.message
      if (message && JSON.parse(message)) {
        push.error({
          message: `敏感词不可出现：${JSON.parse(message).join(',')}`,
          duration: 0,
        })
      }
    }
    if (axiosError.response?.data.code === 502) {
      // 502 企业微信登录错误
      push.error({
        message: `请从YA文件入口进入登录后，再点击该连接，如果有其他问题，请联系 李家彬 解决`,
        duration: 0,
      })
    } else if (error.code === 401) {
      // 处理401的
      // 重新发送一遍请求
      // service.request(axiosError.config as AxiosRequestConfig)
      return handleUnAuthorized(axiosError)
    } else {
      showErrorMsg(error)
    }
    // 鉴权错误
    if (axiosError.response?.status === 403) {
      useService404()
    }
  }

  return Promise.reject(axiosError.response)
}

// 403鉴权错误
function useService404() {
  // useUserStroe().loginout()
  // router.replace('/login')
}

// 处理401的
let promiseFlashing: Promise<void> | null = null
async function handleUnAuthorized(axiosError: AxiosError) {
  const userStore = useUserStore()
  if (!promiseFlashing) {
    promiseFlashing = userStore.getNewToken()
  }
  try {
    // 捕捉这一个错误
    await promiseFlashing
    return service.request(axiosError.config as AxiosRequestConfig)
  } catch (e: any) {
    console.log(e)
    // 获取refreshToken接口报错
    // 直接重新登陆
    // 获取登陆的key
    const { data } = await generateLoginKey({
      timestamp: Date.now(),
      type: 1,
      userId: userStore.userInfo?.userId || '',
    })
    // 清理sessionStorage
    localStorage.clear()
    await userStore.getUserInfoByCode({
      code: data,
      isCodeLogin: 1,
    })
    window.location.reload()

    // console.log(e)
    // create401ErrorMsg()
    // userStore.clearAllUserInfo()
    // return Promise.reject(e)
  } finally {
    promiseFlashing = null
  }
}

// let msgIns: PushClearMethods | null = null

// function create401ErrorMsg() {
//   if (!msgIns) {
//     msgIns = push.error({
//       message: '重新获取token失败，请关闭标签页，重新打开',
//       duration: 0,
//     })
//   }
//   return msgIns
// }
