<script setup lang="ts">
import * as OSS from 'ali-oss'
import '@/lib/aliyun-upload-sdk/aliyun-upload-sdk-1.5.3.min.js'
import { VideoPlay } from '@element-plus/icons-vue'
import { getUploadVideoAuth, updateUploadVideoAuth } from '@/api/base'
;(window as any).OSS = OSS
// 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(['success'])

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

const fileChange = (event: Event) => {
  const element = event.currentTarget as HTMLInputElement
  const files: FileList | null = element.files
  if (!files) return
  for (const file of files) {
    // 是否重复上传
    const hasRepeat = !!fileList.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 = uploader._uploadList
}
function updateFileList(uploadInfo: UploadInfo) {
  if (!uploadInfo) return
  fileList = fileList.map(item => {
    if (item.ri === uploadInfo.ri) {
      return { ...item, ...uploadInfo }
    }
    return item
  })
}
function createUploader() {
  return new (window as any).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)
  getUploadVideoAuth({ 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)
}
// 文件上传成功
function onUploadSucceed(uploadInfo: UploadInfo) {
  console.log('onUploadSucceed', uploadInfo)
  updateFileList(uploadInfo)
  emit('success', uploadInfo)
}
//文件上传失败
function onUploadFailed(uploadInfo: UploadInfo, code: number, message: string) {
  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)
  updateUploadVideoAuth({ source_id: uploadInfo.videoId }).then(res => {
    uploader.resumeUploadWithAuth(res.data.UploadAuth)
  })
  updateFileList(uploadInfo)
}
// 全部文件上传结束
function onUploadEnd(uploadInfo: UploadInfo) {
  console.log('onUploadEnd', uploadInfo)
  updateFileList(uploadInfo)
}

// 进度条
function percentage(value: number) {
  return parseFloat((value ? value * 100 : 0).toFixed(2))
}
defineExpose({ uploader, fileList: $$(fileList) })
</script>
<template>
  <div class="upload-video">
    <div class="upload-video__button">
      本地文件
      <input accept=".mp4" type="file" @change="fileChange" />
    </div>
    <div class="tips">推荐视频格式：帧率为25fps\输出码率为4M\输出格式为mp4，建议采用格式工厂等工具处理后上传。</div>

    <ul class="upload-video-list" v-for="(item, index) in fileList" :key="index">
      <li>
        <div class="upload-video-list__item-info">
          <el-icon><VideoPlay /></el-icon>
          <p>{{ item.file?.name }}</p>
        </div>
        <el-progress :stroke-width="2" :percentage="percentage(item.loaded)" v-if="item.loaded !== 1" />
      </li>
    </ul>
  </div>
</template>
<style lang="scss" scoped>
.tips {
  font-size: 12px;
  line-height: 100%;
  color: #999999;
  margin: 10px 0;
}
.upload-video {
  width: 100%;
}
.upload-video__button {
  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;
  cursor: pointer;
  input {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
  }
}
.upload-video-list {
  li {
    padding: 4px;
    transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
    font-size: 14px;
    color: var(--el-text-color-regular);
    margin-bottom: 5px;
    position: relative;
    box-sizing: border-box;
    border-radius: 4px;
    background-color: var(--el-fill-color-light);
  }
  .el-progress {
    font-size: 12px;
    :deep(.el-progress__text) {
      position: absolute;
      right: 0;
      bottom: 4px;
      min-width: auto;
    }
  }
}
.upload-video-list__item-info {
  display: flex;
  align-items: center;
  line-height: 24px;
  overflow: hidden;
  margin-right: 50px;
  p {
    margin-left: 10px;
    flex: 1;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
  }
}
</style>
