<template>
  <wrapper
    class="c-profile"
    fill
    margin
    background
  >
    <div class="l-flex__none l-flex--col center c-profile__header has-padding">
      <div
        class="o-avatar u-pointer"
        @click="onAvatarClick"
      >
        <i
          class="o-avatar__img"
          :style="avatarStyle"
        />
        <i class="o-avatar__upload el-icon-camera" />
        <input
          ref="upload"
          type="file"
          accept="image/*"
          style="display: none;"
          @change="onUpload"
        >
      </div>
      <div class="u-bold">{{ name }}</div>
      <div class="u-relative">
        <i class="c-profile__icon el-icon-user" />
        {{ roleTip }}
      </div>
    </div>
    <div class="l-flex__fill u-overflow-y--auto">
      <el-result
        v-if="error"
        icon="warning"
      >
        <template #extra>
          <el-link
            class="u-pointer"
            type="warning"
            @click="getUserInfo"
          >
            出错了，点击重试
          </el-link>
        </template>
      </el-result>
      <div
        v-else
        class="c-form"
      >
        <div class="c-form__section">
          <span class="c-form__label">手机：</span>
          <el-input
            v-model="phone"
            class="c-form__item"
            @change="onPhoneChange"
            @keydown.enter="$event.target.blur()"
          />
        </div>
        <div class="c-form__section has-bottom-padding">
          <span class="c-form__label">邮箱：</span>
          <el-input
            v-model="email"
            class="c-form__item"
            @change="onEmailChange"
            @keydown.enter="$event.target.blur()"
          />
        </div>
        <div class="c-form__section">
          <i class="o-wechat" />
          <div
            class="has-padding u-pointer"
            :class="color"
            @click="onClickWechat"
          >
            {{ tip }}
          </div>
        </div>
      </div>
    </div>
    <el-dialog
      :visible.sync="showQr"
      custom-class="c-preview"
      width="0"
      @close="onCloseQr"
    >
      <div class="c-wechat has-padding">
        <div class="l-flex--row center has-bottom-padding">
          <i class="c-sibling-item o-wechat" />
          <span class="c-sibling-item u-color--black u-bold">请使用微信扫一扫</span>
        </div>
        <div
          v-loading="loading"
          class="c-wechat__wrapper"
          :class="{ retry }"
          @click="getQr"
        >
          <img
            class="c-wechat__qr"
            :src="qr"
          >
        </div>
      </div>
    </el-dialog>
  </wrapper>
</template>

<script>
import { mapState } from 'vuex'
import {
  userinfo,
  updateUser
} from '@/api/user'
import { Role } from '@/constant'

export default {
  name: 'Profile',
  data () {
    return {
      error: false,
      user: null,
      avatar: '',
      phone: '',
      email: '',
      wechat: '',
      showQr: false,
      qr: '',
      loading: false,
      retry: false
    }
  },
  computed: {
    ...mapState('user', ['name', 'roles']),
    avatarStyle () {
      const avatar = this.avatar
      return avatar ? {
        backgroundImage: `url("${avatar}")`
      } : null
    },
    roleTip () {
      if (this.roles.includes(Role.ADMIN)) {
        return '超级管理员'
      }
      if (this.roles.includes(Role.SUPERVISOR)) {
        return '主管'
      }
      if (this.roles.includes(Role.STAFF)) {
        return '员工'
      }
      return '游客'
    },
    tip () {
      return this.wechat ? '解除绑定' : '绑定微信'
    },
    color () {
      return this.wechat ? 'u-color--error' : 'u-color--primary'
    }
  },
  created () {
    this.$timer = null
    this.$checkTimer = null
    this.getUserInfo()
  },
  beforeDestroy () {
    this.onCloseQr()
    clearInterval(this.$checkTimer)
  },
  methods: {
    onAvatarClick () {
      this.$refs.upload.click()
    },
    onUpload (e) {
      const file = e.target.files[0]
      e.target.value = null
      if (file.size >= 1024 * 1024) {
        this.$message({
          type: 'warning',
          message: '请选择1M以下的图片'
        })
        return
      }
      const reader = new FileReader()
      reader.onload = () => {
        this.avatar = reader.result
      }
      reader.readAsDataURL(file)
    },
    getUserInfo () {
      this.error = false
      userinfo().then(data => {
        // this.avatar = this.getOrCreateAttribute(data, 'avatar', '')
        this.phone = this.getOrCreateAttribute(data, 'phone', '')
        this.email = data.email || ''
        this.wechat = this.getOrCreateAttribute(data, 'wechat', '')
        this.user = data
      }, () => {
        this.error = true
      })
    },
    getOrCreateAttribute (user, key, defaults = '') {
      if (!user.attributes[key]) {
        user.attributes[key] = [defaults]
      }
      return user.attributes[key][0]
    },
    updateUser (data, meesage) {
      return updateUser(this.user.id, data, meesage)
    },
    changeAttribute (key, value, meesage) {
      if (this.user.attributes[key][0] !== value) {
        return this.updateUser({
          attributes: {
            ...this.user.attributes,
            [key]: [value]
          }
        }, meesage).then(
          () => {
            this.user.attributes[key][0] = value
          },
          e => {
            this.resetAttribute(key)
            return Promise.reject(e)
          }
        )
      }
      return Promise.resolve()
    },
    resetAttribute (key) {
      this[key] = this.user.attributes[key][0]
    },
    onPhoneChange () {
      if (!this.phone) {
        this.$message({
          type: 'warning',
          message: '手机号不能为空'
        })
        this.resetAttribute('phone')
        return
      }
      if (!(/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/.test(this.phone))) {
        this.$message({
          type: 'warning',
          message: '手机号格式错误'
        })
        this.resetAttribute('phone')
        return
      }
      this.changeAttribute('phone', this.phone, '更新手机号')
    },
    onEmailChange () {
      if (!this.email) {
        this.$message({
          type: 'warning',
          message: '邮箱不能为空'
        })
        this.resetAttribute('email')
        return
      }
      if (!(/^([a-zA-Z0-9]+[_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/.test(this.email))) {
        this.$message({
          type: 'warning',
          message: '邮箱格式错误'
        })
        this.resetAttribute('email')
        return
      }
      this.updateUser({ email: this.email }, '更新邮箱').then(
        () => {
          this.user.email = this.email
        },
        () => {
          this.email = this.user.email
        }
      )
    },
    onClickWechat () {
      if (this.wechat) {
        this.$confirm('解除绑定后将无法再收到消息推送', '确定解绑微信？', { type: 'warning' }).then(
          () => {
            this.changeAttribute('wechat', '', '解绑微信').then(() => {
              this.wechat = ''
              this.user.attributes.wechat[0] = ''
            })
          }
        )
      } else {
        this.showQr = true
        this.getQr()
      }
    },
    onCloseQr () {
      this.showQr = false
      clearTimeout(this.$timer)
    },
    getQr () {
      if (this.loading || this.qr && !this.retry) {
        return
      }
      this.fetchQr()
    },
    resetQr () {
      clearInterval(this.$checkTimer)
      this.$checkTimer = null
      this.qr = ''
      this.retry = false
    },
    fetchQr () {
      if (!this.showQr) {
        this.qr = ''
        return
      }
      if (!this.qr || this.retry) {
        this.loading = true
      }
      this.retry = false
      clearTimeout(this.$timer)
      new Promise((resolve, reject) => {
        setTimeout(Math.random() + 0.5 | 0 ? resolve : reject, 1000)
      }).then(
        () => {
          if (!this.wechat) {
            this.qr = Math.random()
            this.$timer = setTimeout(this.fetchQr, 5000)
            this.checkBind()
          }
        },
        () => {
          if (!this.wechat) {
            this.retry = true
          }
        }
      ).finally(() => {
        this.loading = false
      })
    },
    checkBind () {
      if (!this.wechat && !this.$checkTimer) {
        this.$checkTimer = setInterval(this.check, 2000)
        setTimeout(() => {
          this.updateUser({
            attributes: {
              ...this.user.attributes,
              wechat: ['9999']
            }
          }, null)
        }, 5000)
      }
    },
    check () {
      userinfo(true).then(data => {
        const wechat = data.attributes.wechat?.[0]
        if (wechat) {
          this.$message({
            type: 'success',
            message: '绑定微信成功'
          })
          this.wechat = wechat
          this.user.attributes.wechat[0] = wechat
          this.onCloseQr()
          this.resetQr()
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.c-profile {
  overflow: hidden;

  &__header {
    justify-content: space-between;
    height: 176px;
    color: #fff;
    line-height: 1;
    background-color: $blue;
  }

  &__icon {
    position: absolute;
    top: 50%;
    transform: translate(calc(-100% - 16px), -50%);
  }
}

.o-avatar {
  display: inline-block;
  position: relative;
  width: 80px;
  height: 80px;
  padding: 2px;
  border-radius: 50%;
  background-color: #fff;

  &__img {
    display: inline-block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: url("~@/assets/icon_avatar.png") 0 0 / 100% 100% no-repeat;
  }

  &__upload {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    right: 0;
    bottom: 0;
    width: 26px;
    height: 26px;
    color: $blue;
    border-radius: 50%;
    background-color: #fff;
  }
}

.o-wechat {
  display: inline-block;
  width: 32px;
  height: 32px;
  background: url("~@/assets/icon_wechat.png") 0 0 / 100% 100% no-repeat;
}

.c-wechat {
  border-radius: $radius;
  background-color: #fff;

  &__wrapper {
    position: relative;
    width: 240px;
    height: 240px;

    &.retry::after {
      content: "点击重试";
      display: inline-flex;
      justify-content: center;
      align-items: center;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      color: $black;
      font-weight: bold;
      background-color: rgba(#fff, 0.8);
      cursor: pointer;
    }
  }

  &__qr {
    display: inline-block;
    width: 100%;
    height: 100%;
  }
}
</style>
