import NP from 'number-precision'
import API from '@/api'
import { showError, Cookie } from '@/util/util.js'
import { getNetwork } from '@/util/contract.js'
import Eos from 'eosjs'

export const actions = {
  setScatter: ({ commit }, scatter) => commit('setScatter', scatter),
  setEos: ({ commit }, eosjs) => commit('setEos', eosjs),
  setAccount: ({ commit }, account) => commit('setAccount', account),
  /**
   * 调起授权登录
	 * @param {Object} store
	 * @param {Object} params
   */
  async doScatterLogin ({ dispatch, commit, state }, h5Router) {
    if (!state.scatter) {
      showError('Please install the scatter', 'Scatter')
    } else {
      // 获取最快主网
      let networkConfig = await getNetwork()

      // 调用getIdentity方法获取用户名
      try {
        var identity = await state.scatter.getIdentity({
          accounts: [networkConfig]
        })
      } catch (error) {
        if (error.type !== 'identity_rejected') {
          showError(error.message)
        }

        return Promise.reject(error)
      }
      let accounts = identity.accounts.find(x => x.blockchain === 'eos')

      let lastAccounts = localStorage.getItem('accounts')

      if (lastAccounts && JSON.parse(lastAccounts).name !== accounts.name) {
        await actions.doScatterLogout(...arguments)
        h5Router.push({ path: '/login' })
        commit('setUserInfo', null)
        commit('initChatData')
        commit('initGroupData')
        commit('chatAppLogin', false)
        commit('toApp', true)
      }

      commit('setAccount', accounts)
      localStorage.setItem('accounts', JSON.stringify(accounts))

      // 如果当前登录的用户名和cookie中保存的account不一致
      // 则删除cookie中保存的account
      // 避免某些用户在移动端钱包中切换账号时跳过注销流程导致账号不一致的问题
      // if (Cookie.getCookie('account') !== accounts.name) {
      //   Cookie.delCookie('account')
      // }
      // 设置全局EOS对象
      window.EOS = state.scatter.eos(networkConfig, Eos, {})

      // 调用scatter登录成功后获取用户EOS、GT
      // dispatch('getUserEOS')
      // dispatch('getUserGT')
      await dispatch('getAccount')

      // 每分钟刷新一次
      // this.limitTimer = setInterval(() => {
      //   dispatch('getAccount')
      // }, 60000)

      return Promise.resolve(true)
    }
  },
  /**
   * eos账号绑定
   * @param {*} param0
   */
  async doScatterBind ({ dispatch, commit, state }) {
    if (!state.scatter) {
      showError('Please install the scatter', 'Scatter')
    } else {
      // 获取最快主网
      let networkConfig = await getNetwork()

      // 调用getIdentity方法获取用户名
      try {
        var identity = await state.scatter.getIdentity({
          accounts: [networkConfig]
        })
      } catch (error) {
        if (error.type !== 'identity_rejected') {
          showError(error.message)
        }

        return Promise.reject(error)
      }

      let accounts = identity.accounts.find(x => x.blockchain === 'eos')
      window.EOS = state.scatter.eos(networkConfig, Eos, {})

      // 合约登录
      let { data } = await API.user.getRandom2({ account: accounts.name })
      let random = data.data.random
      let accessToken = data.data.accessToken

      let trx = null
      let eos = window.EOS || state.scatter.eos
      let contract = await eos.contract('meechatadmin')

      trx = await contract.login(accounts.name, random, { authorization: [`${accounts.name}@${accounts.authority}`] })

      let param = {
        account: accounts.name,
        access_token: accessToken,
        trx_id: trx.transaction_id || trx.transaction.transaction_id
      }

      return API.user.eosBind2(param)
    }
  },
  /**
   * 注销当前scatter账号
	 * @param {Object} store
	 * @param {Object} params
   */
  doScatterLogout ({ commit, state }, params) {
    Cookie.delCookie('user_id')
    Cookie.delCookie('token')
    localStorage.removeItem('user_id')
    localStorage.removeItem('token')
    localStorage.removeItem('accounts')
    commit('setUserId', null)
    commit('setToken', null)
    // sessionStorage.removeItem('vuex')

    commit('setAccount', '')

    return state.scatter && state.scatter.forgetIdentity && state.scatter.forgetIdentity()
  },

  /**
   * 更新用户EOS币数量
	 * @param {Object} store
	 * @param {Object} params
   */
  getUserEOS ({ dispatch, commit, state }, params) {
    return new Promise((resolve, reject) => {
      window.EOS.getCurrencyBalance('eosio.token', state.account.name, 'EOS').then(([ balance ]) => {
        let balanceNum = Number(balance.replace(/\sEOS/, '')).toFixed(4)

        balanceNum = NP.times(balanceNum, 10000)

        commit('setBalance', balanceNum)
        commit('setEOSError', 0)

        resolve()
      }).catch(error => {
        // 失败重新尝试，最大尝试5次
        commit('setEOSError', state.eosErrorCount + 1)

        if (state.eosErrorCount <= 5) {
          setTimeout(() => {
            dispatch('getUserEOS')
          }, 1000 * state.eosErrorCount)
        }

        reject(error)
      })
    })
  },
  /**
   * 获取用户信息
	 * @param {Object} store
	 * @param {Object} params
   */
  getAccount ({ commit, state }, params) {
    return new Promise((resolve, reject) => {
      window.EOS.getAccount(state.account.name).then(data => {
        // 设置公钥
        const perms = JSON.parse(JSON.stringify(data.permissions))
        perms.forEach(v => {
          if (v.perm_name === 'active') {
            let publicKey = v.required_auth.keys[0].key
            commit('setPublicKey', publicKey)
          }
        })

        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

  /**
   * 进行验证身份登录，生成业务登录态token
	 * @param {Object} store
	 * @param {Object} params
   */
  async doGameLogin ({ dispatch, commit, state }, params) {
    let userId = localStorage.getItem('user_id')
    let token = localStorage.getItem('token')
    if (userId && token) {
      commit('setUserId', userId)
      commit('setToken', token)
      return Promise.resolve({
        user_id: userId,
        token: token
      })
    } else {
      let rData = await API.user.getRandom({ account: state.account.name })
      let random = rData.data.data
      let pubkey = state.publicKey

      return new Promise((resolve, reject) => {
        state.scatter.getArbitrarySignature(pubkey, random, 'Need Login').then(sign => {
          let param = {
            account: state.account.name,
            sign,
            pubkey,
            data: random
          }

          API.user.eosLogin(param).then(({ data }) => {
            if (data.result === 1) {
              let userId = data.data.user_id
              let token = data.data.token
              localStorage.setItem('user_id', userId)
              localStorage.setItem('token', token)

              commit('setUserId', userId)
              commit('setToken', token)

              resolve(data)
            } else {
              reject(new Error(data.msg))
            }
          })
        }).catch(error => {
          reject(error)
        })
      })
    }
  },
  /**
   * 登录态过期，清除当前登录态相关数据，重新调起登录
	 * @param {Object} store
	 * @param {Object} params
   */
  async resetGameLogin ({ dispatch, commit, state }, params) {
    localStorage.removeItem('user_id')
    localStorage.removeItem('token')
    await dispatch('doContractLogin')
    if (self !== top) {
      location.replace(location.href.replace('show=false', 'show=true'))
    } else {
      location.reload()
    }
  },
  /**
   * 合约登录, 生成业务登录态token
	 * @param {Array} params
   */
  async doContractLogin ({ commit, state }, params) {
    let userId = localStorage.getItem('user_id')
    let token = localStorage.getItem('token')
    if (userId && token) {
      commit('setUserId', userId)
      commit('setToken', token)
      return Promise.resolve({
        user_id: userId,
        token: token
      })
    } else {
      try {
        // 合约登录
        let { data } = await API.user.getRandom2({ account: state.account.name })
        let random = data.data.random
        let accessToken = data.data.accessToken
        let identity = { authorization: [`${state.account.name}@${state.account.authority}`] }

        let trx = null
        if (self !== top) {
          trx = await window.postMessager.send({
            action: 'meechat:eosAction',
            data: {
              contract: 'meechatadmin',
              action: 'login',
              param: [state.account.name, random, identity]
            }
          })
        } else {
          let eos = window.EOS || state.scatter.eos
          let contract = await eos.contract('meechatadmin')
          trx = await contract.login(state.account.name, random, identity)
        }

        let param = {
          account: state.account.name,
          access_token: accessToken,
          trx_id: trx.transaction_id || trx.transaction.transaction_id,
          group_id: state.group.groupId || null
        }

        let res = await API.user.eosLogin2(param)
        if (res.data.result === 1) {
          let userId = res.data.data.user_id
          let token = res.data.data.token

          localStorage.setItem('user_id', userId)
          localStorage.setItem('token', token)

          commit('setUserId', userId)
          commit('setToken', token)

          return Promise.resolve(res.data)
        }
      } catch (error) {
        return Promise.reject(error)
      }
    }
  },
  /**
   * @des 获取热门群组
  */
  getHotList ({ state }, params) {
    if (state.hotList.length > 0) return

    API.group.getHotList().then(({ data }) => {
      state.hotList = data.data
    })
  }
}
