<template>
  <container mode="container-xxs">
    <a-form-model class="yo-form">
      <h4 class="h4">我的信息</h4>
      <div class="yo-avatar-info">
        <yo-image :id="form.avatar" :size="128" icon="user" type="avatar" />
        <div @click="onAvatarStart" class="yo-avatar-info--cover">
          <a-icon type="cloud-upload-o" />
        </div>
      </div>
      <br />
      <a-card v-if="avatar.cropper">
        <a-row :gutter="16" align="middle" type="flex">
          <a-col :span="12">
            <div class="yo-avatar-cropper">
              <vue-cropper
                :auto-crop-height="avatar.autoWidth"
                :auto-crop-width="avatar.autoHeight"
                :img="avatar.img"
                @real-time="(data) => avatar.preview = data"
                auto-crop
                fixed-box
                info
                ref="cropper"
              />
            </div>
          </a-col>
          <a-col :span="12">
            <div class="yo-avatar-preview" v-html="avatar.preview.html"></div>
          </a-col>
          <a-col :span="12" class="mt-md text-center">
            <a-upload
              :before-upload="onBeforeUpload"
              :show-upload-list="false"
              class="mr-xs"
              name="file"
            >
              <a-button icon="picture" type="primary">选择图片</a-button>
            </a-upload>
            <a-button-group>
              <a-button @click="$refs.cropper.changeScale(1)" icon="zoom-in" />
              <a-button @click="$refs.cropper.changeScale(-1)" icon="zoom-out" />
              <a-button @click="$refs.cropper.rotateLeft()" icon="undo" />
              <a-button @click="$refs.cropper.rotateRight()" icon="redo" />
            </a-button-group>
          </a-col>
          <a-col :span="12" class="mt-md text-center">
            <a-button
              :loading="avatar.uploading"
              @click="onAvatarOk"
              class="mr-xs"
              icon="check"
              type="primary"
            >确认</a-button>
            <a-button @click="onAvatarCancel" icon="close">取消</a-button>
          </a-col>
        </a-row>
      </a-card>

      <div class="yo-form-group yo-form--short">
        <a-form-model-item label="昵称">
          <a-input placeholder="请输入昵称" v-model="form.nickName" />
        </a-form-model-item>
        <a-form-model-item label="用户名">
          <span>{{ form.name }}</span>
        </a-form-model-item>
        <a-form-model-item label="生日">
          <a-date-picker
            @change="(date) => form.birthday = date ? $moment(date).format('YYYY-MM-DD') : null"
            class="w-100-p"
            placeholder="请选择生日"
            v-model="form.birthday"
          />
        </a-form-model-item>
        <a-form-model-item label="性别" prop="sex">
          <a-radio-group v-model="form.sex">
            <a-radio-button :value="0">
              <a-icon class="mr-xxs" type="stop" />
              <span>保密</span>
            </a-radio-button>
            <a-radio-button :value="1">
              <a-icon :style="{ color: '#1890ff' }" class="mr-xxs" type="man" />
              <span>男</span>
            </a-radio-button>
            <a-radio-button :value="2">
              <a-icon :style="{ color: '#eb2f96' }" class="mr-xxs" type="woman" />
              <span>女</span>
            </a-radio-button>
          </a-radio-group>
        </a-form-model-item>
        <a-form-model-item label="电话" prop="tel">
          <a-input placeholder="请输入电话" v-model="form.tel" />
        </a-form-model-item>
      </div>

      <a-button :loading="saving" @click="onSaveInfo" block>更新个人信息</a-button>
    </a-form-model>
    <br />
  </container>
</template>
<style lang="less" scoped>
@import (reference) '~@/assets/style/extend.less';
.yo-avatar-info {
  position: relative;

  overflow: hidden;

  width: 128px;
  margin: 0 auto;

  border-radius: 50%;
  &--cover {
    font-size: @font-size-lg * 2;

    position: absolute;
    top: 0;
    left: 0;

    display: flex;
    align-items: center;
    justify-content: center;

    width: 100%;
    height: 100%;

    cursor: pointer;
    transition: @animation-duration-slow;

    opacity: 0;
    color: @white;
    background-color: fade(@black, 50%);
    &:hover {
      opacity: 1;
    }
  }
}
.yo-avatar-cropper {
  min-width: 240px;
  height: 240px;

  widows: 100%;
}
.yo-avatar-preview {
  overflow: hidden;

  width: 200px;
  height: 200px;
  margin: 0 auto;

  border-radius: 50%;
  background: #ccc;
}

</style>
<script>
import { BlobToFile } from '@/util/file';
import { setGlobal } from '@/util/global';

import { VueCropper } from 'vue-cropper';

export default {
  components: {
    VueCropper,
  },

  data() {
    return {
      form: {},

      avatar: {
        cropper: false,
        img: '',
        autoWidth: 200,
        autoHeight: 200,

        uploading: false,

        preview: {},
        file: null,
      },

      saving: false,
    };
  },

  watch: {
    'avatar.cropper'(value) {
      if (value) {
        this.avatar.key = Date.now();
      }
    },
  },

  created() {
    this.form = this.$_.cloneDeep(this.$root.global.info);
  },

  methods: {
    onRefreshInfo() {
      return this.$api.getLoginUser().then(async ({ data }) => {
        // 去除应用和菜单信息,存储基本信息
        const info = this.$_.cloneDeep(data);
        delete info.apps;
        delete info.menus;
        setGlobal(info);

        this.form = this.$_.cloneDeep(this.$root.global.info);
      });
    },

    onBeforeUpload(file) {
      this.avatar.file = file;
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => {
        this.avatar.img = reader.result;
      };
      return false;
    },

    onAvatarStart() {
      this.avatar.cropper = true;
    },

    onAvatarOk() {
      this.avatar.uploading = true;
      this.$refs.cropper.getCropBlob(async (data) => {
        try {
          const file = BlobToFile(data, this.avatar.file.name, this.avatar.file.type);
          const fd = new FormData();
          fd.append('file', file);
          const { data: fileId } = await this.$api.sysFileInfoUpload(fd);
          this.form.avatar = fileId;

          this.onAvatarCancel();
        } finally {
          this.avatar.uploading = false;
        }
      });
    },

    onAvatarCancel() {
      this.avatar = {
        ...this.avatar,
        ...{
          cropper: false,
          img: '',
          preview: {},
          file: null,
        },
      };
    },

    async onSaveInfo() {
      this.saving = true;
      try {
        await this.$api.sysUserUpdateInfo({
          avatar: this.form.avatar,
          nickName: this.form.nickName,
          birthday: this.form.birthday,
          sex: this.form.sex,
          tel: this.form.tel,
        });
        await this.onRefreshInfo();
        this.$message.success('更新个人信息成功');
      } finally {
        this.saving = false;
      }
    },
  },
};
</script>