import axios, { type AxiosInstance, type AxiosRequestConfig } from 'axios'
import { handleBackendError, handleRequestError, handleResponseError } from './error'
import type { BackendServiceResult } from './types'
import { useUserStore } from '@/stores/user'

export default class DhRequest {
  instance: AxiosInstance

  constructor(axiosConfig: AxiosRequestConfig) {
    this.instance = axios.create(axiosConfig)
    this.setRequestInterceptor()
    this.setResponseInterceptor()
  }

  // 设置请求拦截器
  setRequestInterceptor() {
    this.instance.interceptors.request.use(
      async (config) => {
        const userStore = useUserStore()
        const token = userStore.token
        if (token) {
          config.headers.Authorization = token
        }

        return config
      },
      (error) => {
        return handleRequestError(error)
      },
    )
  }
  // 设置响应拦截器
  setResponseInterceptor() {
    this.instance.interceptors.response.use(
      (response) => {
        if (response.status >= 200 && response.status < 300) {
          const backendResult = response.data as BackendServiceResult<unknown>
          if (!backendResult.success) {
            // 处理后端错误
            return handleBackendError(backendResult)
          }
          // 设置token
          // if (response.headers.authorization) {
          //   const userStore = useUserStore()
          //   userStore.setToken(response.headers.authorization)
          //   // 存在本地
          //   localStorage.setItem('token', response.headers.authorization)
          // }
          return response.data
        } else {
          // 处理请求成功后错误
          return handleResponseError(response)
        }
      },
      (error) => {
        // 处理请求错误
        return handleRequestError(error)
      },
    )
  }

  /**
   * 请求函数
   * 1. 传入泛型T，T为后端返回的data类型，默认any
   * 2. 传出一个Promise类型的BackendServiceResult<T>，具体为：
   * 	{
   * 		code:string,
   * 		data:T,
   * 		message:string
   *  }
   */
  async request<T>(config: AxiosRequestConfig) {
    try {
      const res = (await this.instance.request(config)) as BackendServiceResult<T>
      return res
    } catch (error) {
      return Promise.reject(error as BackendServiceResult<T>)
    }
  }
}
