import HttpRequest from '@/utils/httpRequest'
import config from '@/config'
import store from '@/store'
import router from '@/router'
const baseUrlMap = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro

class MFetch {
  constructor(apiConfig, verify, alertServerErrMsg, clearAdminInfo) {
    if (!apiConfig) {
      throw new Error('apiConfig is required, please refer to the api_config_demo.js file')
    }

    if (!verify) {
      throw new Error('verify is required, please refer to the verify_demo.js file')
    }

    if (!alertServerErrMsg) {
      console.info('better alert better experience~')
      alertServerErrMsg = window.alert
    }
    this.apiConfig = apiConfig
    this.verify = verify
    this.alertServerErrMsg = alertServerErrMsg
    this.httpMap = {}
    for (let key in baseUrlMap) {
      this.httpMap[key] = new HttpRequest(baseUrlMap[key])
    }

    if (clearAdminInfo) {
      this.clearAdminInfo = clearAdminInfo
    }

    return this.doFetch.bind(this)
  }

  checkStatus(response) {
    if (response.status >= 200 && response.status < 300) {
      return response
    } else if (response.status === 401) {
      let error = new Error('clearAdminInfo')
      throw error
    } else {
      let error
      if(response.data.message==="repetitive_operation_fail"){
        error = new Error("请勿重复操作!")
      }else{
        error = new Error(response.statusText)
      }
      error.response = response
      throw error
    }
  }

  doFetch(config = {}) {
    if (config.apiName && this.apiConfig[config.apiName]) {
      config = { ...this.apiConfig[config.apiName], ...config }
    }

    let {
      type,
      url,
      postData = {},
      success,
      error,
      failed,
      complete,
      method = 'POST',
      notNeedVerify,
      dealReqData,
      dealUrl,
      requireAuth = true,
      isUpload = false,
      onUploadProgress,
      header={}
    } = config
    
    if (!type || !this.httpMap[type]) {
      type = 'root'
    }

    if (dealReqData) {
      postData = dealReqData(postData)
    }
    if (dealUrl) {
      url = dealUrl(url, postData)
    }

    let headers = {
      'token': store.state.token || '',
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'ip': '0.0.0.0',
      'version': '1.0.0',
      'platform': 'chrome',
      'type': 2,
      ...header
    }
    if (isUpload) {
      headers['Content-Type'] = 'multipart/form-data'
      let formData = new FormData()
      formData.append('file', postData)
      postData = formData
    }
    let requestConfig = {
      method,
      headers,
      url,
      data: postData
    }
    if (!isUpload) {
      requestConfig.timeout = 25 * 1000
    }
    if (!isUpload && method.toUpperCase() == 'GET') {
      requestConfig.params = postData
    }
    if (isUpload && onUploadProgress) {
      requestConfig.onUploadProgress = onUploadProgress
    }
    
    return this.httpMap[type].request(requestConfig).then(this.checkStatus)
      .then(res => {
        complete && complete()
        if (notNeedVerify) {
          success && success(res.data)
          return null
        } else {
          let alertServerErrMsg = this.alertServerErrMsg
          let clearAdminInfo = this.clearAdminInfo
          return this.verify({ res, success, error, alertServerErrMsg, clearAdminInfo, url })
        }
      })
      .catch(e => {
        complete && complete()
        if (failed) {
          failed(e)
        } else {
          if (requireAuth && e.message === 'clearAdminInfo') {
            if (store.getters.hasLogin) {
              setTimeout(() => {
                router.push({ name: 'home' })
              }, 1000);
            }
            this.alertServerErrMsg("会话过期，请重新登录！")
           
            this.clearAdminInfo()
          } else {
            this.alertServerErrMsg(e.message)
          }
        }
      })
  }
}

export default MFetch
