import { login, logout as userLogout, getValidCode, refreshAccessToken, resetPasswd, register, getRegisterOpen, wcLogin } from '@/api/oauth2/user'
// 验权
import { getToken, updateToken, removeToken, removeRefreshToken, setUuid, removeUuid } from '@/utils/auth'

export default {
  namespaced: true,
  actions: {
    /**
     *  @description 获取验证码
     *
     */
    getCaptcha({ dispatch }, {
      params
    } = {}) {
      return new Promise((resolve, reject) => {
        getValidCode(params).then(response => {
          resolve(response)
        }).catch(error => {
          reject(error)
        })
      })
    },
    /**
     *  @description 是否开启注册
     *
     */
    getRegisterOpen() {
      return new Promise((resolve, reject) => {
        getRegisterOpen().then(response => {
          resolve(response)
        }).catch(error => {
          reject(error)
        })
      })
    },
    /**
     * @description 登录
     * @param {Object} context
     * @param {Object} payload username {String} 用户账号
     * @param {Object} payload password {String} 密码
     * @param {Object} payload route {Object} 登录成功后定向的路由对象 任何 vue-router 支持的格式
     */
    login({ dispatch }, {
      form
    } = {}) {
      return new Promise(async(resolve, reject) => {
        // 开始请求登录接口
        login(form).then(async response => {
          const data = response.data
          dispatch('updataTokenInfo', data)
          // 设置 vuex 用户信息
          dispatch('ibps/user/setAccount', form.username, { root: true })
          // 结束
          resolve(data)
        }).catch(err => {
          console.error('err: ', err)
          reject(err)
        })
      })
    },
    /**
     * @description 微信登录
     * @param {Object} context
     * @param {Object} payload code {String} 微信请求code
     * @param {Object} payload route {Object} 登录成功后定向的路由对象 任何 vue-router 支持的格式
     */
    loginByWechat({ dispatch }, {
      form
    } = {}) {
      return new Promise(async(resolve, reject) => {
        // 开始请求登录接口
        wcLogin(form).then(async response => {
          const data = response.data

          dispatch('updataTokenInfo', data)
          // 设置 vuex 用户信息
          dispatch('ibps/user/setAccount', form.username, { root: true })
          // 结束
          resolve(data)
        }).catch(err => {
          console.error('err: ', err)
          reject(err)
        })
      })
    },
    /**
     * 更新token 用户信息
     * @param {*} param0
     * @param {*} data
     */
    updataTokenInfo({
      commit,
      dispatch
    }, data) {
      // 设置 cookie 一定要存 uuid 和 token 两个 cookie
      // 整个系统依赖这两个数据进行校验和存储
      // uuid 是用户身份唯一标识 用户注册的时候确定 并且不可改变 不可重复
      // token 代表用户当前登录状态 建议在网络请求中携带 token
      // 如有必要 token 需要定时更新，默认保存一天
      updateToken(data)
      setUuid(data.uid)
    },
    /**
     * 忘记密码
     * @param {*} param context 上下文
     * @param {*} form 表单
     */
    resetPasswd({
      commit,
      dispatch
    }, form) {
      return new Promise(async(resolve, reject) => {
        // 开始请求重置密码接口
        resetPasswd(form).then(response => {
          resolve()
        }).catch(err => {
          console.error('err: ', err)
          reject(err)
        })
      })
    },
    /**
     * 注册帐号
     * @param {*} param context 上下文
     * @param {*} form 表单
     */
    register({
      commit,
      dispatch
    }, form) {
      return new Promise(async(resolve, reject) => {
        // 开始请求注册接口
        register(form).then(response => {
          resolve()
        }).catch(err => {
          console.error('err: ', err)
          reject(err)
        })
      })
    },
    /**
     * @description 注销用户并返回登录页面
     * @param {Object} param context 上下文
     * @param {Object} param vm {Object} vue 实例
     * @param {Object} param confirm {Boolean} 是否需要确认
     */
    logout({
      commit,
      dispatch
    }, {
      vm,
      confirm = false
    }) {
      // 判断是否需要确认
      return new Promise(async(resolve, reject) => {
        dispatch('logoff', { vm }).then(() => {
          resolve(vm)
        }).catch(() => {
          reject(vm)
        })
      })
    },
    /**
     * 注销,包含后台登出和前台清除token
     */
    logoff({ dispatch }, { vm }) {
      const token = getToken()
      return new Promise(async(resolve, reject) => {
      // 如果token过期直接登出
        if (token === null || token === '') {
          dispatch('fedLogout', { vm }).then(() => {
            resolve(vm)
          }).catch(() => {
            reject(vm)
          })
        } else {
        // 后台登出
          userLogout(token).then(() => {
            dispatch('fedLogout', { vm }).then(() => {
              resolve(vm)
            }).catch(() => {
              reject(vm)
            })
          }).catch(() => {
            dispatch('fedLogout', { vm }).then(() => {
              resolve(vm)
            }).catch(() => {
              reject(vm)
            })
          })
        }
      })
    },
    /**
     * 前台登出
     */
    fedLogout({
      commit,
      dispatch
    }, vm) {
      return new Promise(async(resolve, reject) => {
        dispatch('ibps/user/setAccount', '', { root: true })
        dispatch('ibps/user/set', {}, { root: true })

        // 删除一系列cookie
        removeToken()
        removeUuid()
        removeRefreshToken()
        // 删除用户信息

        resolve(vm)
      })
    },
    /**
     * 刷新token
     * @param {*} param0
     * @param {*} token
     */
    refreshToken({
      commit,
      dispatch
    }) {
      return new Promise(async(resolve, reject) => {
        await refreshAccessToken().then(response => {
          const data = response.data
          // 更新token信息
          updateToken(data)
          resolve(data)
        }).catch(err => {
          console.error('refreshAccessToken-err: ', err)
          removeRefreshToken()
          reject(err)
        })
      })
    },
    /**
     * 加载登录后的信息
     * @param {*} param0
     * @param {*} param1
     */
    loadInfo({
      commit,
      dispatch
    }, {
      addRouters = [],
      menus
    }) {
      return new Promise(async resolve => {
        await dispatch('load')
      })
    },
    /**
     * @description 用户登录后从持久化数据加载一系列的设置
     * @param {Object} context
     */
    load({ dispatch }) {
      return new Promise(async resolve => {
        // DB -> store 加载用户名
        await dispatch('ibps/user/get', null, { root: true })
        // end
        resolve()
      })
    }
  }
}
