/**
 * API 请求
 *
 */

import md5 from 'md5'
import store from '@/store'
import config from '@/config'
import cache from '@/plugins/cache'
import { toast } from '@/plugins/util'
import { stringify } from 'qs'

function sortParams(params) {
  return Object.keys(params)
    .filter(k => params[k] !== '') // 过滤空参数
    .sort() // 排序
    .reduce((obj, key) => {
      obj[key] = params[key]
      return obj
    }, {})
}
function sort_ASCII(obj) {
  var arr = new Array()
  var num = 0
  for (let i in obj) {
    arr[num] = i
    num++
  }
  var sortArr = arr.sort()
  var sortObj = {}
  for (let i in sortArr) {
    sortObj[sortArr[i]] = obj[sortArr[i]]
  }
  return sortObj
}
/**
 * 排序参数并生成签名
 */
function generateSign(params = {}) {
  // 随机字符串
  const nonce_str = Math.random().toString(36).substr(2)

  // 排序参数并转 URL 键值对
  const strTemp = sortParams(Object.assign(params, { nonce_str }))

  console.log(strTemp)
  let arr = sort_ASCII(strTemp)
  let str = ''
  for (let key in arr) {
    if (arr[key] || arr[key] === 0) {
      str = str + key + '=' + arr[key] + '&'
    }
  }
  // 生成 MD5 签名
  let sign = md5(str + 'appKey=1f26fe1a6a36daf7651d6437bb6a5fa6').toUpperCase()
  // const sign = md5(
  //   `${strTemp}&appKey=1f26fe1a6a36daf7651d6437bb6a5fa6`
  // ).toUpperCase();
  return {
    ...params,
    nonce_str,
    sign,
  }
}
/**
 * 判断 response 状态
 */
function checkRes(res) {
  if (!res) {
    return {
      code: 500,
      data: '',
      msg: '请求失败，接口异常',
    }
  }

  if (res.statusCode === 404) {
    return {
      code: 404,
      data: '',
      msg: '请求失败，接口不存在',
    }
  }

  if (![200, 304].includes(res.statusCode)) {
    return {
      code: res.statusCode || 400,
      data: '',
      msg: res.statusText || '解析失败，数据异常',
    }
  }

  return res.data
}

/**
 * 判断 data 状态
 * 状态码详情: http://doc.cq1080.com/shares/YPAtNiPWaJGhMmUL#code
 */
function checkCode(res) {
  switch (res.code) {
    case 200:
    case 204:
      return res.data
    case 401:
      toast('登录信息已过期，请重新登录', () => {
        store.commit('removeUserInfo')
        uni.reLaunch({ url: '/pages/index/index' })
      })
      break
    case 403:
      toast('请求失败，暂无权限')
      break
    case 426:
      toast('当前接口需要升级')
      break
    default:
      toast(res.msg || '发生了一个未知错误')
      break
  }
}

/**
 * 接口请求
 *
 * url      地址
 * data     参数
 * method   类型
 * loading  是否显示加载
 */
export function request(url, data, method, loading) {
  const header = {
    'ssdmn-token': cache.get('token'),
  }
  if (method === 'POST') {
    header['Content-Type'] = 'application/json; charset=UTF-8'
  }
  // if (url == '/user/login/smsCodeLogin') {
  //   header['Content-Type'] = 'multipart/form-data'
  // }
  if (loading) {
    // 显示 loading
    uni.showLoading({
      title: method === 'UPLOAD' ? '上传中...' : '加载中...',
      mask: true,
    })
  }
  return new Promise((resolve, reject) => {
    if (method === 'UPLOAD') {
      header['Content-Type'] = 'application/x-www-form-urlencoded'
      uni.uploadFile({
        header,
        url: `${config.server}${url}`,
        name: 'file',
        files: Array.isArray(data) ? data : null,
        filePath: Array.isArray(data) ? null : data,
        success(res) {
          store.commit('setApiError', '')
          resolve(checkCode(JSON.parse(checkRes(res))))
        },
        fail(err) {
          store.commit('setApiError', err?.errMsg)
          reject(err)
        },
        complete(res) {
          console.log({
            PATH: url,
            DATA: res.data?.data,
            REQ: {
              server: `${config.server}${url}`,
              params: data,
              STRING: JSON.stringify(data),
            },
            RES: res,
          })
          uni.stopPullDownRefresh() // 停止下拉刷新
          uni.hideLoading() // 关闭 loading
        },
      })
    } else {
      uni.request({
        method,
        header,
        url: `${config.server}${url}`,
        data: data,
        timeout: 30000, // 30秒超时
        success(res) {
          store.commit('setApiError', '')
          resolve(checkCode(checkRes(res)))
        },
        fail(err) {
          store.commit('setApiError', err?.errMsg)
          reject(err)
        },
        complete(res) {
          console.log({
            PATH: url,
            DATA: res.data?.data,
            REQ: {
              server: `${config.server}${url}`,
              params: data,
              STRING: JSON.stringify(data),
            },
            RES: res,
          })
          uni.stopPullDownRefresh() // 停止下拉刷新
          uni.hideLoading() // 关闭 loading
        },
      })
    }
  })
}

/**
 * get
 *
 * url      地址
 * data     参数
 * loading  是否显示加载
 */
export function get(url, data, loading = false) {
  return request(url, data, 'GET', loading)
}

/**
 * post
 *
 * url      地址
 * data     参数
 * loading  是否显示加载
 */
export function post(url, data, loading = false) {
  return request(url, data, 'POST', loading)
}

/**
 * upload
 *
 * url      地址
 * data     资源路径
 * loading  是否显示加载
 */
export function upload(url, files, loading = true) {
  return request(url, files, 'UPLOAD', loading)
}

// Request
export default { request, get, post, upload }
