<template>
  <el-upload class="w-auto" :action="uploadUrl" :headers="headers" list-type="text" :file-list="props.fileList"
    :data="extraParams" :multiple="props.isMultiple" :accept="props.acceptType" :auto-upload="true"
    :on-remove="handleRemove" :show-file-list="true" :before-upload="beforeUpload" :on-progress="onProgress"
    :on-success="onSuccess">
    <div class="el-upload__text">
      <el-icon class="avatar-uploader-icon">
        <Upload />
      </el-icon>
      <span>{{ props.buttonText }}</span>
    </div>
    <template #tip v-if="!props.isDisableUpload && isShowTips">
      <div class="el-upload__tip">
        <span>支持{{ acceptTypeDesc }}；</span> <span v-if="isLimitSize">文件大小不能超过{{
          props.maxFileSize }}M</span>
      </div>
    </template>
  </el-upload>
</template>

<script lang="ts" setup>
import { Close, Upload, Download, Plus, Link, DeleteFilled } from "@element-plus/icons-vue";
import { defineComponent, ref } from 'vue'
import * as qiniu from 'qiniu-js'
import { qiniuUploadToken } from '@/api/qiniu/index'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { Action, UploadProps, UploadUserFile } from 'element-plus'
const emits = defineEmits(["success", "fileRemove"]);
interface Props {
  acceptType?: string; // 上传文件类型
  acceptTypeDesc?: string; // 描述 - 上传文件类型
  isMultiple?: boolean; //   是否可批量上传
  isLimitSize?: boolean;//是否限制大小
  isShowTips?: boolean;
  maxFileSize?: number; // 文件大小
  isCheckName?: boolean; //   是否检查文件名
  limitNum?: number; // 允许上传文件的最大数量
  formType?: string;//上传的文件字段名称
  buttonText?: string;//上传的文件字段名称
  fileList?: any; // 回显的文件
  public_video_url?: string; // 封面
}
// 接收父组件传递过来的参数
const props = withDefaults(defineProps<Props>(), {
  acceptType: ".mp4",
  acceptTypeDesc: ".mp4",
  formType: "file",
  maxFileSize: 1000,
  isMultiple: true,
  isLimitSize: false,
  isShowTips: false,
  isCheckName: true,
  limitNum: 10,
  fileList: [],
  buttonText: '上传文件',
  public_video_url: ''
});
const uploadUrl = ref('')
const extraParams = ref({})
const token = ref('')
const headers = ref({})
const progress = ref(0)
const uploading = ref(false)
const video = inject('video')
const loadingInstance = ref({})
const uploadedFiles = ref([]); // 用于保存已上传完成的文件
// 校验上传文件格式
const getType = (acceptType: string) => {
  let val = "";
  switch (acceptType) {
    case ".mp4":
      val = "mp4";
      break;
    case ".avi":
      val = "avi";
      break;
    case ".wmv":
      val = "wmv";
      break;
  }
  return val
};
const getToken = async () => {
  try {
    const res = await qiniuUploadToken()
    token.value = await res.data
    if (token.value) {
      headers.value = {
        Authorization: `${token.value}`,
      }
    }
    var config = {
      checkByServer: true,
      checkByMD5: true,
      forceDirect: false,
      useCdnDomain: true,
      disableStatisticsReport: false,
      retryCount: 6,
      region: qiniu.region.z0,
      debugLogLevel: 'INFO'
    };
    qiniu.getUploadUrl(config, token.value).then(res => {
      console.log(res, 'getUploadUrlgetUploadUrl');
      uploadUrl.value = res
    })
  } catch (error) {
    console.error(error)
    ElMessage.error('获取上传凭证失败')
  }
}

const beforeUpload = (file: File) => {
  const fileNamePrefix = file.name.split('.')[0]
  console.log(file.name, 'file.namefile.name', fileNamePrefix);
  if (!/^\d+$/.test(fileNamePrefix) && props.isCheckName) {
    ElMessage.error(`文件命名错误，请以数字命名，例：1.mp4; 11.mp4; 333.mp4`);
    return false
  }
  const filetype = file.type;
  const list = props.acceptTypeDesc.split("/");
  let acceptTypeList = list.map((its: string) => {
    console.log(its, 'itsits', filetype, file);
    return getType(its)
  })
  // 如果要检索的字符串值没有出现，则该方法返回 -1
  const ars = acceptTypeList.filter((q: string) => {
    return filetype.indexOf(q) > -1
  })
  // 用于校验是否符合上传条件
  const type = props.acceptTypeDesc.replace("/", ", ");
  console.log(type, 'typetype');
  if (ars.length < 1) {
    ElMessage.error(`仅支持格式为${type}的图片`);
    return false;
  }
  if (file.size / 1024 / 1024 > props.maxFileSize && props.isLimitSize) {
    ElMessage.error(`文件大小不能超过${props.maxFileSize}MB!`);
    return false;
  }
  console.log(file, '$(prefix)-$(year)-$(fname)$(ext)');
  uploading.value = true
  const fname = `${Date.now()}_${file.name}`
  extraParams.value = {
    key: `${fname}`, token: token.value, 'x:video_id': video.value.id
  }
  if (checkFileName(file, false)) {
    loadingInstance.value = ElLoading.service({
      text: "正在上传视频",
      background: "rgba(0,0,0,.2)",
    });
  } else {
    return checkFileName(file)
  }

}

const onProgress = (event: ProgressEvent) => {
  progress.value = Math.floor((event.loaded / event.total) * 100)
}

const handleRemove: UploadProps['onRemove'] = (file, uploadFiles) => {
  console.log(file, 'filefile');
  if (file && file.status === "success") {
    console.log(file, uploadFiles, 'UploadPropsUploadPropshandleRemove')
    emits('fileRemove', file)
  }
}

const onSuccess = (response: any, uploadFile?: any, uploadFiles?: any) => {
  emits('success', response)
  console.log(props.public_video_url);
  uploadedFiles.value.push(response)
  props.fileList.push({ name: response.fname, url: props.public_video_url, ...response })
  ElMessage.success('上传成功')
  if (uploadFiles.length == uploadedFiles.value.length) {
    loadingInstance.value.close();
    uploading.value = false
  }
}

const onError = (error: any) => {
  uploading.value = false
  ElMessage.error('上传失败')
  console.error(error)
}

const upload = (file: File) => {

  const key = `${Date.now()}_${file.name}`
  extraParams.value = {
    key, token: token.value
  }
  setTimeout(() => {
    const observable = qiniu.upload(file, key, token.value)
    observable.subscribe({
      next: (res) => {
        progress.value = res.total.percent
      },
      error: (err) => {
        onError(err)
      },
      complete: (res) => {
        onSuccess(res)
      },
    })
  }, 50);

}

const checkFileName = (file: File, isShowTips = true) => {
  const fileName = file.name
  if (fileNameList.value.includes(fileName)) {
    console.log(fileName);
    if (isShowTips) {
      ElMessageBox.alert(`上传失败，《${fileName}》文件名已存在，请修改后重新上传`)
    }
    return false
  } else {
    fileNameList.value.push(fileName)
    return true
  }
}

const fileNameList = ref<string[]>([])

onMounted(() => {
  getToken()
})
</script>

<style lang="scss" scoped>
:deep(.el-upload__text) {
  width: 106px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  border: 1px solid rgba(0, 0, 0, 0.15);

  span {
    font-size: 14px;
    padding-left: 6px;
    font-family: PingFangSC-Regular, PingFang SC;
    font-weight: 400;
    color: rgba(0, 0, 0, 0.65);
  }
}
</style>
