/**
* @description: axios封装 - 请求拦截、相应拦截、错误统一处理
* @param {*}
* @return {*}
*/
import axios from 'axios'
import QS from 'qs'
import { Loading, Message } from 'element-ui'
import _ from 'lodash'

// loading对象
let loadingInstance

// 请求合并只出现一次loading
// 当前正在请求的数量
let loadingRequestCount = 0

// 请求超时时间
axios.defaults.timeout = 10000

// post请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'

// 请求拦截器
axios.interceptors.request.use(
  config => {
    let loadingTarget = '#app'
    if (config.headers.loadingTarget) {
      loadingTarget = config.headers.loadingTarget
    }
    const target = document.querySelector(loadingTarget)
    if (target) {
      // 请求拦截进来调用显示loading效果
      showLoading(loadingTarget)
    }
    return config
  },
  error => Promise.error(error)
)

// 响应拦截器
axios.interceptors.response.use(
  response => {
    setTimeout(() => {
      hideLoading()
    }, 200)
    return Promise.resolve(response)
  },
  error => {
    Message.error(`请求错误: ${error}`)
    setTimeout(() => {
      hideLoading()
    }, 200)
    if (error.response.status) {
      return Promise.reject(error.response)
    }
  }
)

// 显示loading的函数 并且记录请求次数 ++
const showLoading = (target) => {
  if (loadingRequestCount === 0) {
    loadingInstance = Loading.service({
      lock: true,
      text: '加载中...',
      target: target
    })
  }
  loadingRequestCount++
}

// 隐藏loading的函数，并且记录请求次数
const hideLoading = () => {
  if (loadingRequestCount <= 0) return
  loadingRequestCount--
  if (loadingRequestCount === 0) {
    toHideLoading()
  }
}

// 防抖：将 300ms 间隔内的关闭 loading 便合并为一次. 防止连续请求时, loading闪烁的问题。
var toHideLoading = _.debounce(() => {
  loadingInstance.close()
  loadingInstance = null
}, 300)

/**
 * post方法，对应post请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function post(url, params) {
  return new Promise((resolve, reject) => {
    axios.post(url, QS.stringify(params))
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err.data)
      })
  })
}

/**
 * get方法，对应get请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function get(url, param) {
  return new Promise((resolve, reject) => {
    axios.get(url, { params: param })
      .then(response => {
        resolve(response)
      }, err => {
        reject(err)
      })
      .catch((error) => {
        reject(error)
      })
  })
}
export default axios
