<template>
  <div class="fbg-upload">
    <div v-if="type === 'file'">
      <fbg-button v-show="isShowButton" type="primary" @click="handleUpload"><i class="fbgiconfont icon-shangchuan"/>&nbsp;&nbsp;{{uploadButtonText}}</fbg-button>
      <input class="fbg-upload-main" :accept="accept" type="file" :multiple="multiple" ref="mainRef" @change="handleChange"/>
      <slot />
      <div class="fbg-upload-tip"><slot name="tip" /></div>
      <ul class="fbg-upload-file">
        <li v-for="(item, index) in value" :key="index"  class="fbg-upload-file-item" @click="handleClickItem(item)">
          <i class="fbgiconfont icon-shoucang1" />
          {{item[nameMap]}}
          <i class="fbgiconfont icon-guanbishanchu fbg-upload-file-close"  @click.stop="hanleRemove(item[urlMap], index)"/>
        </li>
        <li v-if="isUploading" class="fbg-upload-file-item">
          <fbg-progress :percentage="uploadingData.percent" />
        </li>
      </ul>
    </div>
    <div v-else-if="type === 'image'">
      <input class="fbg-upload-main" :accept="accept" type="file" :multiple="multiple" ref="mainRef" @change="handleChange"/>
      <ul class="fbg-upload-image">
        <li class="fbg-upload-image-item" v-for="(item, index) in value" :key="index">
          <div class="fbg-upload-image-box">
            <img :src="item[urlMap]" />
            <div class="fbg-upload-image-box-modal">
              <div>
                <i class="fbg-icon-view" style="margin-right: 5px" @click="handleLookat(item[urlMap], index)"/>
                <i class="fbg-icon-delete" @click="hanleRemove(item[urlMap], index)"/>
              </div>
            </div>
          </div>
        </li>
        <li v-if="isUploading"  class="fbg-upload-image-item">
          <div class="fbg-upload-image-box">
            <fbg-progress type="circle" :width="80" :percentage="uploadingData.percent"/>
          </div>
        </li>
        <li v-show="isShowButton" class="fbg-upload-image-button" @click="handleUpload">
          <i class="fbg-icon-plus" />
        </li>
      </ul>
      <slot />
      <div class="fbg-upload-tip"><slot name="tip" /></div>
      <fbg-dialog title="查看大图" width="540px" :visible.sync="visableImage">
        <div class="fbg-dialog-body">
          <img class="fbg-upload-big-image" :src="imageSrc" />
        </div>
      </fbg-dialog>
    </div>
    <div v-else>
      <input class="fbg-upload-main" :accept="accept" type="file" ref="mainRef" @change="handleChange" />
      <div style="display: flex">
        <el-input :value="files[0]?files[0].name:''" style="flex: 1" @click="handleUpload" readonly :placeholder="placeholder" @close="handleClear"/>&nbsp;
        <fbg-button type="primary" @click="handleSingUpload" ><i class="fbgiconfont icon-shangchuan"/>&nbsp;&nbsp;{{uploadButtonText}}</fbg-button>
      </div>
      <slot />
      <div class="fbg-upload-tip"><slot name="tip" /></div>
      <div class="fbg-upload-file-item">
        <fbg-progress v-if="uploadingData" :percentage="uploadingData.percent" />
      </div>
    </div>
  </div>
</template>
<script>
import Button from '../button';
import Dialog from '../dialog';
import {Progress} from 'element-ui';
import util from '../../utils';

export default {
  components: {
    'fbg-button': Button,
    'fbg-dialog': Dialog,
    'fbg-progress': Progress
  },
  props: {
    type: {
      type: String,
      default: ''
    },
    action: {
      type: String,
      default: '/',
    },
    params: {
      type: Object,
      default() {
        return {};
      }
    },
    maxlength: {
      type: Number,
      default: 9999
    },
    uploadButtonText: {
      type: String,
      default: '上传'
    },
    placeholder: {
      type: String,
      default: '未选择文件'
    },
    accept: {
      type: String,
      default: ''
    },
    format: {
      type: Array,
      default() {
        return null;
      }
    },
    multiple: {
      type: Boolean,
      default: false
    },
    autoUpload: {
      type: Boolean,
      default: true
    },
    size: {
      type: Number,
      default: 0
    },
    headers: {
      type: Object,
      default() {
        return {};
      }
    },
    value: {
      type: [String, Array, Object],
      default: ''
    },
    urlMap: {
      type: String,
      default: 'url'
    },
    nameMap: {
      type: String,
      default: 'name'
    },
    onSuccess: {
      type: Function,
      default() {
        return function() {};
      }
    }
  },
  computed: {
    isShowButton() {
      return (this.multiple && this.value.length < this.maxlength) || (!this.multiple && !this.value);
    }
  },
  data() {
    return {
      files: [],
      uploadList: [],
      visableImage: false,
      isUploading: false,
      uploadingData: null,
      imageSrc: '',
    };
  },
  methods: {
    handleLookat(src) {
      this.$emit('onLookat', src);
      this.openBigImage(src);
    },
    hanleRemove(src, index) {
      if(this.$emit('onRemove', src, index) !== false) {
        this.value.splice(index, 1);
        this.$emit('input', this.value);
      }
    },
    handleClickItem(item) {
      this.$emit('clickItem', item);
    },
    handleUpload() {
      this.$refs.mainRef.click();
    },
    handleChange(e) {
      const files = this.files = [].slice.call(e.target.files);
      this.upload(files);
    },
    handleSingUpload() {
      this.next();
    },
    submit() {
      this.next();
    },
    openBigImage(src) {
      this.imageSrc = src;
      this.visableImage = true;
    },
    upload(files) {
      let flag = true;
      for (let i = 0; i<files.length; i++ ){
        const file = files[i];
        const filereader = new FileReader();
        if (!this.checkFile(file, files)) {
          return false;
        }
        const obj = {
          percent: 0,
          [this.urlMap]: '',
          [this.nameMap]: ''
        };
        filereader.onload = (e) => {
          this.$emit('onPreview', e.target.result, file);
          this.uploadList.push(() => {
            this.uploadingData = obj;
            this.isUploading = true;
            this.uploadRequest(file, () => {
              this.next();
            });
          });

          if (flag && this.autoUpload) {
            this.next();
            flag = false;
          }
        }
        filereader.readAsDataURL(file);
      };
      this.$refs.mainRef && (this.$refs.mainRef.value = '');
    },
    updateValue(data) {
      if (this.multiple) {
        this.value.push(data);
        this.$emit('input', this.value);
      } else {
        this.$emit('input', data);
      }
    },
    next() {
      if (this.uploadList.length) {
        const uploadFun = this.uploadList.shift();
        uploadFun();
      }
    },
    checkFile(file, files) {
      const filename = file.name;
      const formatName = filename.match(/\.([a-zA-Z0-9]*)$/)[1];
      const size = file.size;
      if (this.format && this.format.length) {
        if (this.format.indexOf(formatName) === -1) {
          this.$emit('checkError', {
            type: 'format',
            file: file
          });
          return false;
        }
      }
      if (this.maxlength) {
        if (this.value.length + files.length > this.maxlength) {
          this.$emit('checkError', {
            type: 'maxlength',
            file: file
          });
          return false;
        }
      }
      if (this.size) {
        if (parseInt(size/1000) > this.size) {
          this.$emit('checkError', {
            type: 'size',
            file: file
          });
          return false;
        }
      }
      return true;
    },
    
    handleClear() {
      if (this.$refs.mainRef) {
        this.$refs.mainRef.value = '';
        this.files = [];
      }
    },
    uploadRequest(file, callback) {
      var formdata = new FormData();
      formdata.append("file", file);
      var xhr = new XMLHttpRequest();
      xhr.open("post", this.action, true);
      xhr.onreadystatechange =  () => {
        if (xhr.readyState==4 && xhr.status==200) {
          let res = null;
          try {
            res = JSON.parse(xhr.response);
          } catch(e) {
            console.warn(e)
          }
          this.isUploading = false;
          this.uploadingData = null;
          const result = this.onSuccess(res, file);
          this.updateValue(result);
          // this.$emit('onProgress', obj, file);
          // this.$emit('onSuccess', res, file);
        } else if (xhr.readyState==4) {
          this.isUploading = false;
          this.$emit('onError', xhr, file);
        }
        callback && callback();
      }
      //获取上传的进度
      xhr.upload.onprogress = (event) => {
        if(event.lengthComputable && this.uploadingData){
          this.uploadingData.percent = event.loaded/event.total *100;
          
        }
      }
      for (let key in this.headers) {
        xhr.setRequestHeader(key,this.headers[key]);
      }
      xhr.send(formdata);
    }
  }
}
</script>
<style lang="scss" scoped>
.fbg {
  &-upload {
    &-tip {
      margin: 10px 0px;
      color: #888;
      font-size: 12px;
    }
    &-big {
      &-image {
        width: 100%;
      }
    }
    &-main {
      width: 1px;
      height: 1px;
      opacity: 0px;
      position: relative;
      z-index: -1;
    }
    &-image {
      margin-top: 10px;
      &-button {
        padding: 3px;
        display: inline-block;
        border: 1px dashed #ccc;
        border-radius: 3px;
        position: relative;
        width: 80px;
        height: 80px;
        line-height: 80px;
        text-align: center;
        overflow: hidden;
        color: #666;
        vertical-align: middle;
        cursor: pointer;
        i {
          font-size: 30px;
          vertical-align: middle;
          color: #999;
        }
      }
      &-item {
        padding: 3px;
        display: inline-block;
        border: 1px dashed #ccc;
        border-radius: 3px;
        vertical-align: middle;
      }
      &-box {
        position: relative;
        width: 80px;
        height: 80px;
        overflow: hidden;
        img {
          width: 100%;
        }
        &-modal {
          width: 100%;
          height: 100%;
          background: rgba(0, 0, 0, 0.6);
          position: absolute;
          top: 0px;
          left: 0px;
          visibility: hidden;
          opacity: 0;
          color: #fff;
          line-height: 80px;
          text-align:center;
          transition: all 0.3s;
          i {
            font-size: 18px;
            cursor: pointer;
          }
        }
        &:hover {
          .fbg-upload-image-box-modal {
            visibility: visible;
            opacity: 1;
          }

        }
      }
      &-close {
        float: right;
        cursor: pointer;
      }
    }
    &-file {
      margin-top: 10px;
      &-item {
        padding: 8px 10px;
        list-style: none;
        overflow: hidden;
        text-overflow:ellipsis;
        white-space: nowrap;
        border-radius: 3px;
        color: #666;
        &:hover {
          background-color: rgba(0, 0, 0, 0.1);
        }
      }
      &-close {
        float: right;
        cursor: pointer;
      }
    }
  }
}
</style>