<template>
  <div >
    <label for="{{ name }}" class="font_normal_body" >
      <input  type="file" class="input_search" name="{{ name }}" id="{{ id || name }}" accept="{{ accept }}"
             v-on:click="fileInputClick" v-on:change="fileInputChange" multiple="{{ multiple }}"
             class="form-control">
      <slot></slot>
    </label>
    <button type="button" style="margin-top: 18px;" v-on:click="fileUpload" class="button_search btn-gn" :id="'vc-fileupload-upload-'+attach">{{ tagname }}</button>
  </div>
</template>

<script>
  export default {
    props: {
      name: {
        type: String,
        required: true
      },
      id: String,
      action: {
        type: String,
        required: true
      },
      accept: String,
      multiple: String,
      headers: Object,
      method: String,
      tagname: String
    },
    data () {
      return {
        myFiles: [] // a container for the files in our field
      }
    },
    methods: {
      fileInputClick: function () {
        // //tag
        // click actually triggers after the file dialog opens
        this.$dispatch('onFileClick', this.myFiles)
      },
      fileInputChange: function (event) {
        // //tag
        // get the group of files assigned to this field
        var ident = this.id || this.name
        // this.myFiles = document.getElementById(ident).files
        // 多个组件同时打开，id相同无法获取文件
        this.myFiles = event.target.files;
        this.$dispatch('onFileChange', this.myFiles)
      },
      _onProgress: function (e) {
        // 这是一个XMLHttpRequest内部调用更新进度
        // this is an internal call in XHR to update the progress
        e.percent = (e.loaded / e.total) * 100
        this.$dispatch('onFileProgress', e)
      },
      _handleUpload: function (file) {
        // 文件上传之前发出一个派发事件
        this.$dispatch('beforeFileUpload', file)
        var form = new FormData()
        var xhr = new XMLHttpRequest()
        try {
          form.append('Content-Type', file.type || 'multipart/form-data')
          // form.append('Content-Type', 'application/x-www-form-urlencoded')
          // our request will have the file in the ['file'] key
          form.append('file', file)
        } catch (err) {
          this.$dispatch('onFileError', file, err)
          return
        }

        return new Promise(function (resolve, reject) {
          xhr.upload.addEventListener('progress', this._onProgress, false)

          xhr.onreadystatechange = function () {
            if (xhr.readyState < 4) {
              return
            }
            if (xhr.status < 400) {
              var res = JSON.parse(xhr.responseText)
              this.$dispatch('onFileUpload', file, res)
              resolve(file)
            } else {
              var err = JSON.parse(xhr.responseText)
              err.status = xhr.status
              err.statusText = xhr.statusText
              this.$dispatch('onFileError', file, err)
              reject(err)
            }
          }.bind(this)

          xhr.onerror = function () {
            var err = JSON.parse(xhr.responseText)
            err.status = xhr.status
            err.statusText = xhr.statusText
            this.$dispatch('onFileError', file, err)
            reject(err)
          }.bind(this)

          xhr.open(this.method || 'POST', this.action, true)
          if (this.headers) {
            for (var header in this.headers) {
              xhr.setRequestHeader(header, encodeURIComponent(this.headers[header]))
            }
          }
          // xhr.send(form + '&username=' + this.username + '&BlobId=' + this.blob_id)
          xhr.send(form)
          this.$dispatch('afterFileUpload', file)
        }.bind(this))
      },
      fileUpload: function () {
         if (this.myFiles.length > 0) {
          // 将具有length属性的对象转成数组，除了IE下的节点集合（因为ie下的dom对象是以com对象的形式实现的，js对象与com对象不能进行转换）
          // a hack to push all the Promises into a new array
          var arrayOfPromises = Array.prototype.slice.call(this.myFiles, 0).map(function (file) {
            //tag
            return this._handleUpload(file)
          }.bind(this))
          // wait for everything to finish
          Promise.all(arrayOfPromises).then(function (allFiles) {
            // 所有文件上传完成
            this.$dispatch('onAllFilesUploaded', allFiles)
          }.bind(this)).catch(function (err) {
            this.$dispatch('onFileError', this.myFiles, err)
          }.bind(this))
        } else {
          // someone tried to upload without adding files
          // 没有选择文件就进行上传
          // var err = new Error('No files to upload for this field')
          //tag
          this.$showAlert('未选择任何文件，请重新选择要上传的文件','warning',2000)
          var err = new Error('未选择任何文件，请选要上传的文件')
          this.$dispatch('onFileError', this.myFiles, err)
        }
      }
    }
  }
</script>
