<template>
  <div style="width: 100%;max-height: 45vh">
    <el-upload
      ref="upload"
      style="width: 100%;"
      :http-request="customUpload"
      action="#"
      :limit="5"
      :file-list="fileList"
      :auto-upload="false"
      :show-file-list="false"
      :on-change="handleChange"
      :on-exceed="handleExceed"
      :on-remove="handleRemove"
      :accept="accept"
      :before-upload="beforeUpload"
      :directory="true"
      :on-success="handleSuccess"
    >
      <el-row :gutter="24">
        <el-col :span="1.5">
          <el-button icon="el-icon-upload2" :disabled="disabled" size="small" type="primary">上传文件</el-button>
        </el-col>
      </el-row>
    </el-upload>
    <div style="margin-top: 10px; text-align: right;">
      总文件大小: {{ (totalFileSize / (1024 * 1024 * 1024)).toFixed(2) }} GB
    </div>
    <el-table :data="Object.entries(uploadProgress)" style="width: 100%">
      <el-table-column prop="0" label="文件名" align="center" show-overflow-tooltip>
        <template slot-scope="scope">
          <span>{{ scope.row[0] }}</span>
        </template>
      </el-table-column>
      <el-table-column label="上传进度" align="center">
        <template slot-scope="scope">
          <el-progress :color="scope.row[1] === 100 ? '#13ce66' : '#6E6A6A4C'" :percentage="scope.row[1]"
          ></el-progress>
        </template>
      </el-table-column>
      <el-table-column label="状态" align="center">
        <template slot-scope="scope">
          <i v-if="scope.row[1] === 100 && !uploadFailed[scope.row[0]]" style="color: #13ce66; font-size: 18px;"
             class="el-icon-success"
          ></i>
          <i v-if="scope.row[1] !== 100 && !uploadFailed[scope.row[0]]"
             style="font-size: 18px; color: rgba(110,106,106,0.3);" class="el-icon-upload"
          ></i>
          <i v-if="uploadFailed[scope.row[0]]" style="font-size: 18px; color: red;" class="el-icon-warning"></i>
        </template>
      </el-table-column>
      <el-table-column label="错误信息" align="center">
        <template slot-scope="scope">
          <span v-if="uploadFailed[scope.row[0]]" style="font-size: 12px; color: red;">文件上传失败</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center">
        <template slot-scope="scope">
          <el-button
            v-if="scope.row[1] !== 100 && !uploadFailed[scope.row[0]]"
            type="text"
            size="mini"
            @click="handleClose(scope.row[0], fileList)"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import { uploadFiles } from '@/utils/upload'
import { parseTime } from '@/utils/bonus'

export default {
  name: 'miniFileUpload',
  props: {
    paramsData: {
      type: Object,
      default: {}
    },
    parentId: {
      type: String,
      required: true
    },
    fileUrl: {
      type: String,
      required: true
    },
    disabled: {
      type: Boolean,
      default: false
    },
    getList: {
      type: Function
    }
  },
  data() {
    return {
      totalFileSize: 0,
      fileList: [],
      chunkSize: 1024 * 1024 * 20,
      uploadProgress: {},
      uploadFailed: {},
      queue: [],
      maxConcurrentUploads: 5,
      uploadsNum: {},
      videoDuration: 0,
      stopName: '',
      accept:".doc, .docx, .xls, .xlsx, .ppt, .pptx, .pdf, .mp4, .txt",
      submittedArr:[]
    }
  },
  beforeMount() {
    this.resetComponent()
  },
  mounted() {
    this.resetComponent()
  },
  methods: {
    startUpload() {
      this.$refs.upload.submit()
    },
    async handleSuccess(res, file) {
      // Handle success logic here
    },
    getFileDuration(content) {
      return new Promise((resolve) => {
        const videoElement = document.createElement('video')
        videoElement.src = URL.createObjectURL(content)
        videoElement.addEventListener('loadedmetadata', function() {
          resolve(videoElement.duration)
        })
      })
    },
    handleClose(name,fileList) {
      this.fileList = fileList
      const item = fileList.find(item => item.name === name)
      this.totalFileSize -= item.size
      this.fileList = fileList.filter(item => item.name !== name)
      //从上传队列中移除
      this.queue = this.queue.filter(item => item.name !== name)
      //从上传进度中移除
      delete this.uploadProgress[name]
      //从上传失败中移除
      delete this.uploadFailed[name]
      this.stopName = name
    },
    resetComponent() {
      this.fileList = []
      this.uploadProgress = {}
      this.uploadFailed = {}
      this.queue = []
      this.uploadsNum = {}
      this.submittedArr = []
      this.totalFileSize = 0
    },
    customUpload(uploadFile) {
      const file = uploadFile.file
      for (let item of this.fileList) {
        if (item.duration && item.name === file.name) {
          file.duration = item.duration
        }
      }
      this.queue.push(file)
      this.startNextUpload()
    },
    handleChange(file, fileList) {
      //根据this.accept 判断file.name的类型是否符合标准
      const reg = new RegExp(`(${this.accept.split(',').map(item => item.trim().replace('.','\\.')).join('|')})$`)
      if (!reg.test(file.name)) {
        this.$message.error('文件格式不正确')
        fileList.pop()
        return false
      }
      let size = 0
      console.log("handleChange",fileList)
      console.log("handleChange",this.fileList)
      fileList.forEach(item => size += item.size)
      this.totalFileSize = size
      if (size > 5 * 1024 * 1024 * 1024) {
        this.$message.error('文件总大小不能超过 5GB')
        this.totalFileSize -= file.size
        fileList.pop()
        return false
      }
      const isExist = this.fileList.some(item => item.name === file.name)
      if(isExist) {
        this.$message.error('文件已存在')
        this.totalFileSize -= file.size
        fileList.pop()
        return false
      }
      if (file && file.raw.type === 'video/mp4') {
        this.getFileDuration(file.raw).then(duration => {
          file.duration = Math.round(duration)
        })
      }else{
        file.duration = 30
      }
      this.$set(this.uploadProgress, file.name, 0)
      this.fileList = fileList
    },
    handleRemove(file, fileList) {
      this.fileList = fileList
    },
    uploadChunks(file) {
      this.$set(this.uploadsNum, file.name, 0)
      const totalChunks = Math.ceil(file.size / this.chunkSize)
      let currentChunk = 0
      const uploadNextChunk = () => {
        const start = currentChunk * this.chunkSize
        const end = Math.min(file.size, start + this.chunkSize)
        const chunk = file.slice(start, end)
        const formData = new FormData()
        formData.append('file', chunk)
        formData.append('filename', file.name)
        formData.append('duration', file.duration)
        formData.append('chunk', currentChunk + 1)
        formData.append('totalChunks', totalChunks)
        formData.append('parentId', this.paramsData.coursewareId)
        formData.append('fileUrl', parseTime(new Date(), '{y}{m}'))
        uploadFiles(formData)
          .then(() => {
            currentChunk++
            const progress = Math.floor((currentChunk / totalChunks) * 100)
            this.$set(this.uploadsNum, file.name, progress)
            this.$set(this.uploadProgress, file.name, progress)
            if (this.stopName === file.name) {
              delete this.uploadProgress[file.name]
              this.stopName = ''
              return
            }
            if (currentChunk < totalChunks) {
              uploadNextChunk()
            } else {
              this.startNextUpload()
              this.checkAllUploadsComplete()
            }
          })
          .catch(() => {
            this.$set(this.uploadFailed, file.name, true)
            this.startNextUpload()
          })
      }
      uploadNextChunk()
    },
    checkAllUploadsComplete() {
      const allComplete = Object.values(this.uploadProgress).every(progress => progress === 100)
      if (allComplete) {
        this.$message.success('所有文件上传完成！')
        this.$emit('uploadSuccess')

      }
    },
    startNextUpload() {
      Object.keys(this.uploadsNum).forEach(fileName => {
        if (this.uploadsNum[fileName] === 100) {
          delete this.uploadsNum[fileName]
        }
      })
      if (this.queue.length === 0 || Object.values(this.uploadsNum).length >= this.maxConcurrentUploads) {
        return
      }
      const nextFile = this.queue.shift()
      if (this.submittedArr.includes(nextFile.name)) {
        this.startNextUpload()
      }else{
        this.submittedArr.push(nextFile.name)
        this.uploadChunks(nextFile)
      }
    },
    stopUpload() {
      this.queue = []
      this.uploadsNum = {}
      this.uploadProgress = {}
      this.uploadFailed = {}
    },
    beforeUpload(file) {
      const maxSize = 2 * 1024 * 1024 * 1024
      if (file.size > maxSize) {
        this.$message.error('文件大小不能超过 2GB')
        return false
      }
      return true
    },
    handleExceed(files, fileList) {
      this.$message.warning(`最多只能选择5个文件，当前选择了 ${files.length + fileList.length} 个文件`)
    }
  }
}
</script>

<style scoped>
.el-upload__tip {
  font-size: 12px;
  color: #909399;
}

.el-dialog__wrapper {
  z-index: 1000 !important;
}
</style>
