import { type RequestOptions, type ResponseData, type ErrorResponse } from './types'
import { HTTP_STATUS, ERROR_MSG } from './config'
import router from '@/router/router'
import db from '@/utils/db'
import toast from '@/utils/hud'

// 请求拦截器
export const requestInterceptor = async (options: RequestOptions): Promise<RequestOptions> => {
  // 设置请求头
  const header: any = {
    ...options?.header,
  }

  // 获取token
  const token = db.get('token')
  // 如果有token，添加到请求头
  if (token) {
    header['Authorization'] = `Bearer ${token}`
  }

  return {
    ...options,
    header,
  }
}

// 响应拦截器
export const responseInterceptor = async <T>(
  response: ResponseData<T>,
): Promise<ResponseData<T>> => {
  const { statusCode, data } = response as any
  console.log('response', response)

  // 处理成功响应
  if (statusCode === HTTP_STATUS.SUCCESS) {
    if (data.code === 200) return response
    throw {
      statusCode,
      errMsg: data.data,
    }
  } else {
    throw {
      statusCode,
    }
  }
}

// 错误拦截器
export const errorInterceptor = (error: any): Promise<ErrorResponse> => {
  let message
  const { statusCode, errMsg } = error
  let toLogin = false
  if (statusCode === HTTP_STATUS.SUCCESS) {
    message = errMsg
  } else {
    // 处理特定状态码
    switch (error.statusCode) {
      case HTTP_STATUS.AUTHENTICATE:
        toLogin = true
        message = ERROR_MSG.AUTH_ERROR
        break

      case HTTP_STATUS.FORBIDDEN:
        toLogin = true
        message = ERROR_MSG.FORBIDDEN_ERROR
        break

      case HTTP_STATUS.NOT_FOUND:
        message = ERROR_MSG.NOT_FOUND_ERROR
        break

      case HTTP_STATUS.SERVER_ERROR:
      case HTTP_STATUS.BAD_GATEWAY:
      case HTTP_STATUS.SERVICE_UNAVAILABLE:
      case HTTP_STATUS.GATEWAY_TIMEOUT:
        message = ERROR_MSG.SERVER_ERROR
        break

      default:
        message = ERROR_MSG.DEFAULT_ERROR
        break
    }
  }

  // 显示错误提示
  if (message) {
    toast.error(message)
    if (toLogin) {
      router.toLogin()
    }
  }

  return Promise.reject({
    code: -1,
    message,
    data: error,
  })
}
