import appConfig from '../config'
import Toast from 'react-native-root-toast'

// 服务器地址
export const API_SERVER = appConfig.API_ROOT

// 是否外部的服务器
export const isOutServer = url => url.indexOf('/') !== 0

// 全局错误码处理
const ERROR_CODE_MAP = {
  // 401: {
  //   message: '',
  //   process: (resp) => {}
  // },
}

const SUCCESS_CODE = 1000;

// 错误处理
const errorProcess = (resp, reject, errorToast) => {
  const resData = resp.data || {}
  let message = resData.message || resData.msg || resp.statusText
  const status = resData.stats || resp.status
  if (ERROR_CODE_MAP[status] && ERROR_CODE_MAP[status].message) {
    message = ERROR_CODE_MAP[status].message
  }
  if (errorToast) {
    Toast.show(message || '', {
      duration: Toast.durations.LONG,
      position: Toast.positions.BOTTOM,
    })
  }
  reject({ message, data: resData })
}

// 处理响应
const responseProcess = (resp, resolve, reject, outServer, errorToast) => {
  if (outServer) {
    return resolve([resp, ''])
  }
  if (resp.code === SUCCESS_CODE) {
    return resolve([resp.data, resp.msg])
  }
  return errorProcess(resp, reject, errorToast)
}

// 封装get post 请求
export const $request = {
  _requestConfig: getRequestInfo,
  async _request(url, method, params, config = {}) {
    const isOutRequest = isOutServer(url)
    let headers = config.headers || {}
    let body = {}
    let errorToast = config.errorToast || true
    url = isOutRequest ? url : `${API_SERVER}${url}`
    // 非外部请求,自定义headers中添加Token等操作
    if (!isOutRequest && this._requestConfig) {
      let composeHeaders = null
      if (typeof this._requestConfig === 'function') {
        composeHeaders = await this._requestConfig(url, method, params, config)
      } else {
        composeHeaders = this._requestConfig
      }
      headers = Object.assign({}, config.headers, composeHeaders)
    }
    if (headers['Content-Type'] === 'multipart/form-data') {
      body = params
    } else if (method === 'POST') {
      body = JSON.stringify(params || {})
    }
    const fetchConfig = {
      method,
      headers,
    }
    if (method === 'POST') {
      fetchConfig.body = body
    }
    return new Promise((resolve, reject) => {
      fetch(url, fetchConfig)
        .then(res => {
          if (res.ok) {
            return res.json()
          }
          errorProcess(res, reject, errorToast)
        })
        .then(json => {
          responseProcess(json, resolve, reject, isOutRequest, errorToast)
        })
        .catch(e => {
          errorProcess({ data: { message: e.message } }, reject, errorToast)
        })
    })
  },
  // GET请求
  get(url, params, config = {}) {
    return this._request(url, 'GET', params, config)
  },
  // POST请求
  post(url, params, config = {}) {
    return this._request(url, 'POST', params, {
      ...config,
      headers: {
        ...(config.headers || {}),
        'Content-Type': 'application/json',
      },
    })
  },
  // POST FORM 请求
  postForm(url, params, config = {}) {
    return this._request(url, 'POST', params, {
      ...config,
      headers: {
        ...(config.headers || {}),
        'Content-Type': 'multipart/form-data',
      },
    })
  },
}