<template>
  <div class="tf-file-uploader">
    <slot name="title">{{ title }}</slot>
    <span style="margin-left: 5px; color: #ccc">(最多上传{{ limit }}张)</span>
    <div
      style="margin-top: 20px"
      class="upload"
      :style="`--display: ${files.length >= limit ? 'none' : 'inline-flex'}`"
    >
      <el-upload :file-list="files" v-on="$listeners" v-bind="attrs">
        <i class="el-icon-plus" />
      </el-upload>
    </div>
    <tf-image-preview :visible.sync="visible" :src="url" />
  </div>
</template>

<script lang="ts">
  import { ElUploadInternalFileDetail } from 'element-ui/types/upload'
  import { Vue, Component, Prop, VModel } from 'vue-property-decorator'

  @Component({ name: 'TfFileUploader', inheritAttrs: false })
  export default class TfFileUploader extends Vue {
    /** v-model value */
    @VModel({ type: Array, default: () => [] }) files!: ElUploadInternalFileDetail[]
    /** 标题 */
    @Prop({ type: String }) title!: string
    /** 最大文件数量 */
    @Prop({ type: Number, default: 9 }) limit!: number
    /** 单文件最大大小  单位：MB */
    @Prop({ type: Number, default: 10 }) maxSize!: number

    url: string = ''
    visible: boolean = false

    get attrs() {
      return {
        listType: 'picture-card',
        multiple: true,
        autoUpload: false,
        action: 'whatever',
        accept: '.jpg,.jpeg,.png',
        drag: true,
        onRemove: this.onRemove,
        onChange: this.onFileChange,
        onPreview: this.onPreview,
        ...this.$attrs
      }
    }

    onRemove(file) {
      this.files = this.files.filter((item) => item.uid !== file.uid)
    }
    onPreview(file) {
      this.url = file.url
      this.visible = true
    }

    async onFileChange(file: ElUploadInternalFileDetail, files: ElUploadInternalFileDetail[]) {
      setTimeout(() => {
        const imageTypes = ['image/jpeg', 'image/png']
        const { size, name, raw: { type } = {} } = file
        const accept = this.attrs.accept.split(',')

        const handleError = (msg) => {
          console.log(msg, '\n', files.length, this.files.length)
          this.$message.error(msg)
          this.onRemove(file)
          return new Error(msg)
        }
        if (!imageTypes.includes(type) || !accept.some((item) => String(name).endsWith(item))) {
          return handleError(`上传文件只能是 ${accept.join(', ')} 格式!`)
        }
        if (size / 1024 / 1024 > this.maxSize) {
          return handleError(`上传文件大小不能超过 ${this.maxSize} MB!`)
        }
        if (this.files.length >= this.limit) {
          return handleError(`最多可以上传${this.limit}张图片!`)
        }
        this.files = [...this.files, file]
        console.log(this.$attrs)
        return true
      }, 0)
    }
  }
</script>

<style lang="scss" scoped>
  .tf-file-uploader {
    .upload {
      overflow: hidden;
      margin-right: -16px;
      >>> .el-upload {
        &-list__item,
        &--picture-card,
        &-dragger {
          width: 130px;
          height: 130px;
          line-height: normal;
          display: inline-flex;
          align-items: center;
          justify-content: center;
        }
        &-dragger {
          width: 100%;
          height: 100%;
          border: none;
        }
        &.el-upload--picture-card {
          display: var(--display);
        }
      }
    }
  }
</style>
