<template>
  <div>
    <div class="file-area">
      <span class="label-text">{{ labelText }}</span>
      <div class="upload-box">
        <el-upload
          ref="upload"
          class="file-uploader"
          action="no"
          :accept="acceptFileType"
          :multiple="true"
          :show-file-list="false"
          :auto-upload="false"
          :on-change="onFileChange"
        >
          <el-button>选取{{ labelText }}文件</el-button>
        </el-upload>
        <el-button size="small" type="primary" @click="uploadFiles">上传</el-button>
      </div>
    </div>
    <el-divider />
    <div class="upload-tip">{{ uploadTip }}</div>
    <ul slot="file-list" class="file-list">
      <li v-for="(file, i) in fileList" :key="i">
        <div class="file-name">
          <span>
            <SvgIcon :icon-class="iconClass" size="12" />
            <span>{{ file.file_name ?? file.name }}</span>
            <!-- <span>({{ file.size }})</span> -->
          </span>
          <span v-if="file.progress > 0 && file.progress < 100"> {{ file.progress }}% </span>
          <span v-else-if="file.file_id"> 完成 </span>
        </div>
        <SvgIcon icon-class="delete-black" size="12" @click="removeFile(file, i)" />
        <SvgIcon
          v-show="type === 'picture' && file.file_id"
          icon-class="mark"
          size="12"
          @click="viewDialog(file.file_id)"
        />
      </li>
    </ul>

    <FillDescribe :file-data="curFile" :visible.sync="visible" @fillDescribeToFile="fillDescribeToFile" />
  </div>
</template>

<script>
import { fileUpload } from '@/api/app';
import { conversionSize } from '@/utils/common';
import FillDescribe from '../../common/FillDescribe.vue';

export default {
  name: 'UploadFile',
  components: {
    FillDescribe,
  },
  inject: ['property'],
  props: {
    // 课件id
    coursewareId: {
      type: String,
      default: '',
    },
    // 组件id
    componentId: {
      type: String,
      default: '',
    },
    // 组件标签
    labelText: {
      type: String,
      default: '',
    },
    // 上传支持的文件格式
    acceptFileType: {
      type: String,
      default: '',
    },
    // 提示语
    uploadTip: {
      type: String,
      default: '',
    },
    // 图标
    iconClass: {
      type: String,
      default: '',
    },
    fileList: {
      type: Array,
      default: () => [],
    },
    fileIdList: {
      type: Array,
      default: () => [],
    },
    fileInfoList: {
      type: Array,
      default: () => [],
    },
    type: {
      type: String,
      default: '',
    },
    singleSize: {
      type: Number,
      default: 100,
    },
    totalSize: {
      type: Number,
      default: 1024,
    },
  },
  data() {
    return {
      curFile: null,
      conversionSize,
      visible: false,
      content: {
        file_list: this.fileList,
        file_id_list: this.fileIdList,
        file_info_list: this.fileInfoList,
      },
    };
  },
  watch: {
    content: {
      handler(val) {
        this.$emit('updateFileList', val);
      },
      deep: true,
    },
    property: {
      handler(val) {
        if (val.isGetContent) {
          this.content = {
            file_list: this.fileList,
            file_id_list: this.fileIdList,
            file_info_list: this.fileInfoList,
          };
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    // 显示自定义样式文件列表
    onFileChange(file, fileList) {
      this.afterSelectFile(file);
      fileList.forEach((file) => {
        if (!file.progress || file.progress <= 0) file.progress = 0;
      });
      const lists = this.$refs.upload.uploadFiles;
      if (lists.length === 0) return;
      lists.forEach((item) => {
        let _index = this.content.file_list.findIndex((p) => p.uid === item.uid);
        if (_index <= -1) {
          this.content.file_list.push(item);
        }
      });
    },

    // 删除文件
    removeFile(file, i) {
      this.$confirm('是否删除当前文件？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(() => {
          this.$refs.upload.handleRemove(file);
          this.content.file_list.splice(i, 1);
          this.content.file_id_list.splice(i, 1);
        })
        .catch(() => {});
    },

    // 文件校验
    afterSelectFile(file) {
      const fileName = file.name;
      let singleSizeTip = `文件[${fileName}]大小超过${conversionSize(this.singleSize * 1024 * 1024)},被移除！`;
      if (file.size > this.singleSize * 1024 * 1024) {
        this.$message.error(singleSizeTip);
        this.$refs.upload.handleRemove(file);
        return false;
      }

      const suffix = fileName.slice(fileName.lastIndexOf('.') + 1, fileName.length).toLowerCase();
      let fileType = [];
      let typeTip = '';

      if (this.type === 'audio') {
        fileType = ['mp3', 'acc', 'wma'];
        typeTip = '音频文件只能是 mp3、acc、wma 格式!';
      } else if (this.type === 'picture') {
        fileType = ['jpg', 'png', 'jpeg'];
        typeTip = '图片文件只能是 jpg、png、jpeg 格式!';
      } else if (this.type === 'video') {
        fileType = ['mp4'];
        typeTip = '视频文件只能是 mp4 格式!';
      }
      const isNeedType = fileType.includes(suffix);
      if (!isNeedType) {
        typeTip += `,[${fileName}]被移除！`;
        this.$message.error(typeTip);
        this.$refs.upload.handleRemove(file);
        return false;
      }
    },

    // 上传文件
    uploadFiles() {
      const files = (this.content.file_list || []).filter((file) => file.uid);
      if (files.length <= 0) {
        this.$message.error('没有需要上传的文件！');
        return false;
      }
      const totalSize = files.reduce((sum, cur) => sum + Number(cur.size || 0), 0);
      if (totalSize > this.totalSize * 1024 * 1024) {
        this.$message.error(`文件总大小不能超过${conversionSize(this.totalSize * 1024 * 1024)}!`);
        return false;
      }

      files
        .filter((p) => {
          let pro = p.progress || -1;
          return pro <= 0;
        })
        .forEach((file) => {
          let form = new FormData();
          form.append(file.name, file.raw, file.name);
          fileUpload('Mid', form, {
            handleUploadProgress: (progressEvent) => {
              // 进度到99等服务器返回文件信息后才算实际完成
              let per = Number((progressEvent.progress * 99).toFixed(2) || 0);
              let en = this.content.file_list.find((p) => p.uid === file.uid);
              if (en) {
                en.progress = per;
                this.$forceUpdate();
              }
            },
          }).then(({ file_info_list }) => {
            let file_index = this.content.file_list.findIndex((p) => p.uid === file.uid);
            if (file_index > -1) {
              if (this.type === 'picture') {
                this.content.file_info_list[file_index] = {
                  file_id: file_info_list[0].file_id,
                  file_name: file_info_list[0].file_name,
                  title: '',
                  intro: '',
                };
              }
              this.content.file_list[file_index] = {
                file_id: file_info_list[0].file_id,
                file_name: file_info_list[0].file_name,
                file_url: file_info_list[0].file_url,
              };
              this.content.file_id_list.push(file_info_list[0].file_id);
              this.$refs.upload.uploadFiles = [];
              this.$forceUpdate();
            }
          });
        });
    },

    // 显示弹窗
    viewDialog(file_id) {
      if (file_id) this.visible = true;
      this.curFile = this.content.file_info_list.find((file) => file.file_id === file_id);
    },

    // 给文件加介绍
    fillDescribeToFile(file) {
      let en = this.content.file_info_list.find((p) => p.file_id === file.file_id);
      if (en) {
        Object.assign(en, file);
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.module-content {
  .file-area {
    display: flex;
    column-gap: 16px;
    align-items: center;

    .label-text {
      font-size: 14px;
      color: $font-light-color;
    }

    div {
      flex: 1;
    }
  }

  .el-divider {
    margin: 16px 0;
  }

  .upload-tip {
    margin-bottom: 16px;
    font-size: 12px;
    color: #86909c;
  }

  .upload-box {
    display: flex;
    justify-content: space-between;

    .file-uploader {
      flex: 1;

      :deep .el-upload {
        &--text {
          width: 100%;
          background-color: $fill-color;
          border-radius: 2px 0 0 2px;

          .el-button {
            width: 100%;
            color: #86909c;
            text-align: left;
          }
        }
      }
    }

    .el-button {
      border-radius: 0 2px 2px 0;
    }
  }

  .old_file_list {
    margin-top: 16px;
  }

  .file-list {
    display: flex;
    flex-direction: column;
    row-gap: 16px;

    li {
      display: flex;
      column-gap: 12px;
      align-items: center;

      .file-name {
        display: flex;
        column-gap: 14px;
        align-items: center;
        justify-content: space-between;
        max-width: 360px;
        padding: 8px 12px;
        font-size: 14px;
        color: #1d2129;
        background-color: #f7f8fa;

        span {
          display: flex;
          column-gap: 14px;
          align-items: center;
        }
      }

      .svg-icon {
        cursor: pointer;
      }
    }
  }
}
</style>
