<script setup lang="ts">
import VideoDetail from './VideoDetail.vue'
import { getCreateAuth, updateAuth } from '@/api/base'
import { CircleClose } from '@element-plus/icons-vue'
const idShowMore = ref(false)

// uploadInfo 包含要上传的文件信息
interface UploadInfo {
  bucket: string
  checkpoint: { file: File; name: string; fileSize: number; partSize: number; uploadId: string }
  endpoint: string
  file: File
  fileHash: string
  isImage: boolean
  loaded: number
  object: string
  region: string
  retry: boolean
  ri: string
  state: string
  userData: string
  videoId: string
  videoInfo: any
  progress: number
}

const emit = defineEmits(['upload', 'canClose'])

let uploader = createUploader()
const fileList = ref<UploadInfo[]>([])

const fileChange = (event: Event) => {
  const element = event.currentTarget as HTMLInputElement
  let files: FileList | null = element.files
  if (!files) return
  for (const file of files) {
    // 是否重复上传
    const hasRepeat = !!fileList.value.find(
      item =>
        item.file.name === file.name && item.file.size === file.size && item.file.lastModified === file.lastModified
    )
    !hasRepeat && uploader.addFile(file, null, null, null, '{"Vod":{}}')
  }
  uploader.startUpload()
  fileList.value = uploader._uploadList
}
function updateFileList(uploadInfo: UploadInfo) {
  if (!uploadInfo) return
  fileList.value = fileList.value.map(item => {
    if (item.ri === uploadInfo.ri) {
      return { ...item, ...uploadInfo }
    }
    return item
  })
}
function createUploader() {
  return new window['AliyunUpload'].Vod({
    //userID，必填，您可以使用阿里云账号访问账号中心（https://account.console.aliyun.com/），即可查看账号ID
    userId: '1303984639806000',
    //上传到视频点播的地域，默认值为'cn-shanghai'，
    //eu-central-1，ap-southeast-1
    region: 'cn-shanghai',
    //分片大小默认1 MB，不能小于100 KB（100*1024）
    partSize: 1048576,
    //并行上传分片个数，默认5
    parallel: 5,
    //网络原因失败时，重新上传次数，默认为3
    retryCount: 3,
    //网络原因失败时，重新上传间隔时间，默认为2秒
    retryDuration: 2,
    //开始上传
    onUploadstarted: onUploadStarted,
    //文件上传成功
    onUploadSucceed: onUploadSucceed,
    //文件上传失败
    onUploadFailed: onUploadFailed,
    //文件上传进度，单位：字节
    onUploadProgress: onUploadProgress,
    //上传凭证或STS token超时
    onUploadTokenExpired: onUploadTokenExpired,
    //全部文件上传结束
    onUploadEnd: onUploadEnd
  })
}
// 开始上传
function onUploadStarted(uploadInfo: UploadInfo) {
  console.log('onUploadStarted', uploadInfo)
  getCreateAuth({ title: uploadInfo.file.name, file_name: uploadInfo.file.name }).then(res => {
    uploader.setUploadAuthAndAddress(uploadInfo, res.data.upload_auth, res.data.upload_address, res.data.source_id)
  })
  updateFileList(uploadInfo)
  emit('canClose', { closeStatus: false })
}
// 文件上传成功
function onUploadSucceed(uploadInfo: UploadInfo) {
  console.log('onUploadSucceed', uploadInfo)
  updateFileList(uploadInfo)
  emit('upload', uploadInfo)
}
//文件上传失败
function onUploadFailed(uploadInfo: UploadInfo, code: number, message: string) {
  console.log(uploadInfo, '111111')
  console.log('onUploadFailed', uploadInfo, code, message)
  updateFileList(uploadInfo)
}
//文件上传进度，单位：字节
function onUploadProgress(uploadInfo: UploadInfo, totalSize: number, loadedPercent: number) {
  console.log('onUploadProgress', uploadInfo.file.name, uploadInfo, totalSize, loadedPercent)
  updateFileList(uploadInfo)
}
//上传凭证或STS token超时
function onUploadTokenExpired(uploadInfo: UploadInfo) {
  console.log('onUploadTokenExpired', uploadInfo)
  updateAuth({ source_id: uploadInfo.videoId }).then(res => {
    uploader.resumeUploadWithAuth(res.data.UploadAuth)
  })
  updateFileList(uploadInfo)
}
// 全部文件上传结束
function onUploadEnd(uploadInfo: UploadInfo) {
  console.log('onUploadEnd', uploadInfo)
  updateFileList(uploadInfo)
  emit('canClose', { closeStatus: true })
}

const handleView = () => {
  idShowMore.value = true
}
// 进度条
function percentage(value: number) {
  return parseFloat((value ? value * 100 : 0).toFixed(2))
}

// 删除上传文件
const deleteFile = function (index: number) {
  console.log(index, 'deleteFile', fileList)
  fileList.value.splice(index, 1)
  uploader.deleteFile(index)
}
defineExpose({ uploader, fileList })
</script>
<template>
  <div class="upload-video" style="display: flex; flex-direction: column; align-items: flex-start">
    <div class="upload-btn">
      本地文件
      <input accept=".mp4" type="file" id="fileUpload" multiple @change="fileChange" />
    </div>
    <div class="tips">推荐视频格式：帧率为25fps\输出码率为4M\输出格式为mp4，建议采用格式工厂等工具处理后上传。</div>
    <div v-for="(item, index) in fileList.slice(0, 3)" :key="index">
      <div class="video-info">
        <span class="name">{{ item.file?.name }}</span>
        <el-progress style="width: 200px" :percentage="percentage(item.loaded)" class="view" />
        <div v-if="percentage(item.loaded) == 100">上传成功</div>
        <el-icon v-else @click="deleteFile(index)"><CircleClose /></el-icon>
      </div>
    </div>
    <el-link style="padding-top: 3px" :underline="false" type="primary" v-if="fileList.length > 3" @click="handleView"
      >共{{ fileList.length }}个文件，查看更多</el-link
    >
  </div>
  <VideoDetail :videoList="fileList" v-model:modelValue="idShowMore" v-if="idShowMore === true" />
</template>
<style lang="scss">
.demo-progress {
  min-width: 350px;
  display: flex;
  span {
    color: #999999;
    font-size: 14px;
    transform: translateX(-20px);
  }
}
#fileUpload {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0.00001;
}
.tips {
  font-size: 12px;
  line-height: 100%;
  color: #999999;
  margin-top: 8px;
}
.upload-video {
  display: flex;
  align-items: center;
  .upload-btn {
    position: relative;
    width: 94px;
    line-height: 36px;
    background: rgba(250, 223, 230, 0.39);
    border: 1px solid #aa1941;
    border-radius: 20px;
    font-size: 14px;
    color: #aa1941;
    margin-right: 30px;
    text-align: center;
  }
  .video-info {
    display: flex;
    align-items: center;
    margin-top: 10px;
    .name {
      color: #333333;
      font-size: 14px;
      line-height: 1.5;
    }
    .view {
      font-size: 16px;
      line-height: 100%;
      margin-left: 20px;
      cursor: pointer;
    }
  }
}
</style>
