import api from '@/api'
import { showError, getUrlParam, getMeechatType, openBlankWindow, getUserOpt, setUserOpt } from '@/util/util'
import { mapActions, mapState, mapMutations } from 'vuex'
import ScatterJS from 'scatter-js/dist/scatter.esm'
import { Message } from 'element-ui'
import PostMessager from '@/util/postMessager.js'

let _timeoutHandler = 0

// 账号登录
export const accountLoginMixin = {
  data () {
    return {
      curLoginType: '', // 当前登录类型[eos,eth,telegram]
      winHandler: null, // 新开窗口
      winTimer: null, // 检测窗口定时器
      meechatType: getMeechatType(),
      from: decodeURIComponent(getUrlParam('from'))
    }
  },
  computed: {
    ...mapState(['isLogining', 'account'])
  },
  methods: {
    ...mapMutations(['setLogining']),
    ...mapActions([
      'getUserInfo',
      'setScatter',
      'setAccount',
      'doScatterLogin',
      'doContractLogin',
      'initSocket'
    ]),
    /**
     * @des 校验本地登录态
    */
    async checkLocalLogin () {
      this.setLogining(true)

      let userId = localStorage.getItem('user_id')
      let token = localStorage.getItem('token')

      if (!userId || !token) {
        this.setLogining(false)
        return false
      }

      let { data } = await api.user.checkLocalLogin({
        user_id: userId,
        token: token
      })

      if (data.data.is_login) {
        this.curLoginType = getUserOpt('loginType') || 'eos'

        if (this.curLoginType == 'eos' && top == self) {
          await this.loginEos()
          this.setLogining(false)
        } else {
          this.$store.commit('setUserId', userId)
          this.$store.commit('setToken', token)
          this.loginSuccCallBack()
        }

        return true
      } else {
        localStorage.clear()
        this.setLogining(false)
        return false
      }
    },
    /**
     * @des 调用父级页面getIdentity
    */
    async getParentIdentity () {
      if (self !== top) {
        try {
          let response = await this.postMessager.send({ action: 'meechat:getIdentity' })
          let account = response.accounts.find(x => x.blockchain === 'eos')

          localStorage.setItem('account', JSON.stringify(account))
          this.setAccount(account)
        } catch (error) {
          this.showLoginBtn = true
        }
      }
    },
    /**
     * @des 内嵌版调用父级eos登录
     * */
    async loginEosParent () {
      this.setLogining(true)
      try {
        // scatter登录
        await this.getParentIdentity()
        if (!this.account) return
        // 合约登录
        await this.doContractLogin()
        location.replace(location.href.replace('show=false', 'show=true'))
        this.showLoginBtn = false
        this.setLogining(false)
      } catch (msg) {
        if (msg.type) {
          // scatter报错的情况
        } else {
          let json = JSON.parse(msg)
          let details = json.error.details
          Message({
            message: details[0].message,
            type: 'error'
          })
        }
        this.showLoginBtn = true
        this.setLogining(false)
      }
    },
    /**
     * @des eos登录
     * */
    loginEos () {
      this.curLoginType = 'eos'

      return new Promise((resolve, reject) => {
        this.setLogining(true)
        // 连接scatter
        ScatterJS.scatter.connect('MEE_CHAT').then(async connected => {
          if (connected) {
            // 设置scatter
            this.setScatter(ScatterJS.scatter)

            // 清空全局scatter引用
            window.ScatterJS = null

            try {
              // 调起scatter授权登录
              await this.doScatterLogin(this.$router)

              if (this.meechatType == 'mini') {
                localStorage.setItem('account', JSON.stringify(this.account))
              }

              // 签名登录
              await this.doContractLogin()

              this.loginSuccCallBack()
            } catch (error) {
              reject(error)
              if (this.meechatType == 'mini') {
                this.showLoginBtn = true
              } else if (this.isLogining) {
                this.$router.replace('/login')
                this.$store.commit('chatAppLogin', false)
              }
            }
            this.setLogining(false)
          } else {
            if (this.meechatType == 'mini') {
              this.showLoginBtn = true
            } else if (this.isLogining) {
              this.$router.replace('/login')
            }

            if (this.isLogining && !localStorage.getItem('user_id')) {
            // 用户scatter未解锁
              showError(this.$t('login.installScatter'), 'Scatter')
            }

            this.setAccount('')
            this.setLogining(false)
          }
          resolve()
        })
      })
    },
    loginSimpleWallet () {
      this.curLoginType = 'simplewallet'
      let param = {
        protocol: 'SimpleWallet',
        version: '1.0',
        dappName: 'MeeChat',
        dappIcon: 'https://static.meechat.me/cdn/mee.chat/dist/img/icons/meechat_icon.png',
        action: 'login',
        uuID: Math.random(),
        loginUrl: location.origin + '/user/simplewallet'
      }

      let url = `simplewallet://eos.io?param=` + JSON.stringify(param)
      this.winHandler = openBlankWindow(url)
      this.loginCheck(param.uuID, 0)
    },
    async loginTelegram () {
      this.curLoginType = 'telegram'
      this.winHandler = openBlankWindow('')

      let { data } = await api.user.tgCSRF({
        type: 'login'
      })

      this.winHandler.location.href = data.data.url

      this.loginCheck(data.data.csrf_token)
    },
    /**
     * @des 轮询校验登录
     * @param {*} uuID
     * @param {Number} times 轮询次数
     * @param {String} 登录类型[eos,eth,telegram]
     */
    async loginCheck (uuID, times) {
      if (times === 0) {
        // 第一次调用
        clearTimeout(_timeoutHandler)
      } else if (times >= 60) {
        return false
      }

      let res = {}
      let isLoginSuccess = false // 是否登录成功
      let isLoginCheck = true // 是否继续校验
      try {
        if (this.curLoginType == 'simplewallet') {
          // 校验eth
          res = await api.user.simplewalletCheck({ uuID })
          isLoginSuccess = res.data && res.data.result === 1
        } else if (this.curLoginType == 'telegram') {
          // 校验telegram
          res = await api.user.tgLogin2({ csrf_token: uuID })
          isLoginSuccess = res.data && res.data.data && res.data.data.status > 0
          isLoginCheck = (this.winHandler != null) || (res.data && res.data.status == 0)
        }
      } catch (ex) {
      }

      if (isLoginSuccess) {
        let userId = res.data.data.user_id
        let token = res.data.data.token

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

        this.$store.commit('setUserId', userId)
        this.$store.commit('setToken', token)
        this.loginSuccCallBack()

        if (this.winHandler != null) {
          this.winHandler.close()
          this.winHandler = null
        }
        return Promise.resolve(res.data)
      } else if (isLoginCheck) {
        // 定时检查是否登录成功
        _timeoutHandler = setTimeout(() => {
          this.loginCheck(uuID, ++times)
        }, 1000)
      }
    },
    async loginSuccCallBack () {
      this.setLogining(false)
      setUserOpt('loginType', this.curLoginType)

      switch (this.meechatType) {
        // 内嵌版
        case 'mini':
          this.$emit('initMiniLoginCallback')
          break
        // h5版本,完整版
        case 'h5':
        case 'pc':
          console.log('loginSuccCallBack, meechatType:' + this.meechatType + ', this.$route.name:' + this.$route.name)
          if (this.meechatType === 'h5' && this.$route.name === 'login') {
            let url = this.from && this.from != 'null' ? this.from : `/`
            console.log('this.$router.replace, url:' + url)
            this.$router.replace(url)
          }

          await this.initSocket()
          this.$store.commit('chatAppLogin', true)
          this.$store.commit('toApp', true)
          break
      }
    }
  },
  mounted () {
    // 内嵌版-初始化postMessage消息管理器
    if (top != self) {
      let callback = (event) => {
        if (event.action === 'meechat:setShow') {
          this.handleToggleChat(event.show)
        } else if (event.action === 'meechat:logout') {
          this.handleLogout2()
        }
      }

      this.postMessager = new PostMessager('*', { callback })
      window.postMessager = this.postMessager
    }
  }
}
