import axios, {
  type AxiosRequestConfig,
  type InternalAxiosRequestConfig,
  type AxiosResponse
} from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import useStore from '@/stores'

// 创建 axios 实例
const service = axios.create({
  baseURL: '/portal',
  timeout: 50000,
  headers: {}
})

// 请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    if (!config.headers) {
      throw new Error(`Expected 'config' and 'config.headers' not to be undefined`)
    }
    // get请求映射params参数
    if (config.method === 'get' && config.params) {
      let url = config.url + '?'
      for (const propName of Object.keys(config.params)) {
        const value = config.params[propName]
        const part = encodeURIComponent(propName) + '='
        if (value !== null && typeof value !== 'undefined') {
          if (typeof value === 'object') {
            for (const key of Object.keys(value)) {
              if (value[key] !== null && typeof value[key] !== 'undefined') {
                const params = propName + '[' + key + ']'
                const subPart = encodeURIComponent(params) + '='
                url += subPart + encodeURIComponent(value[key]) + '&'
              }
            }
          } else {
            url += part + encodeURIComponent(value) + '&'
          }
        }
      }
      url = url.slice(0, -1)
      config.params = {}
      config.url = url
    }
    const { user } = useStore()
    user.tokenValue && (config.headers[user.tokenName] = user.tokenValue)
    return config
  },
  (error: any) => {
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    if ([200].includes(response.data.code) || response.config.third) {
      return response.data
    } else {
      if (response.data.code === 401) {
        ElMessageBox.confirm('当前页面已失效，请重新登录', '提示', {
          confirmButtonText: 'OK',
          type: 'warning'
        }).then(() => {
          window.location.href = '/dcsysui/login'
        })
        return response.data
      }
      // 响应数据为二进制流处理(Excel导出)
      if (response.config.responseType === 'blob') {
        return response
      }
      ElMessage.error(response.data.msg)
      return Promise.reject(response.data.msg)
    }
  },
  (error: any) => {
    console.warn('----- my data is error: ', error)
    if (error.response.status === 500) {
      ElMessage.error('内部服务器错误，请重新登录~~~')
    } else {
      ElMessage.error('系统出错')
    }
    return Promise.reject('2' + error.message)
  }
)

const request = <T, K, F>(
  config: AxiosRequestConfig<T>
): Promise<
  F extends { third: boolean }
    ? K
    : {
        totalRows: number
        code: number
        msg: string
        data: K
      }
> => {
  return service.request(config)
}
export default {
  get: <K = any, F = string, T = {}>(config: AxiosRequestConfig<T>) => {
    return request<T, K, F>({ ...config, method: 'get' })
  },
  post: <K = any, F = string, T = {}>(config: AxiosRequestConfig<T>) => {
    return request<T, K, F>({ ...config, method: 'post' })
  }
}
