<template>
  <view class="video-uploader">
    <up-upload
      :file-list="fileList"
      :max-count="maxCount"
      accept="video"
      :preview-full-image="false"
      :max-size="maxSize * 1024 * 1024"
      @after-read="handleAfterRead"
      @delete="handleDelete"
    >
      <view class="upload-btn">
        <u-icon name="plus" size="32" color="#999"></u-icon>
        <text class="upload-text">{{
          fileList.length ? t("重新选择") : t("选择视频")
        }}</text>
      </view>
    </up-upload>

    <!-- 预览 -->
    <view v-if="fileList.length" class="preview">
      <video class="preview-video" :src="fileList[0].url" controls></video>
    </view>

    <!-- 上传进度 -->
    <u-line-progress
      v-if="uploading"
      :percentage="progress"
      stroke-width="6"
      active-color="#3c9cff"
      :show-text="true"
      class="preview"
    />
  </view>
</template>

<script setup>
import { ref, watch } from "vue";
import { $uploadFile, Toast } from "@/utils";
import { t } from "@/locale";

const props = defineProps({
  // 初始图片列表
  modelValue: {
    type: Array,
    default: () => [],
  },
  // 最大上传数量
  maxCount: {
    type: Number,
    default: 1,
  },
  maxSize: {
    type: Number,
    default: 50,
  },
  // 是否多选
  multiple: {
    type: Boolean,
    default: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  // 上传按钮文字
  uploadText: {
    type: String,
    default: "上传图片",
  },
});
const fileList = ref([]);
const uploading = ref(false);
const progress = ref(0);

const emit = defineEmits(["update:modelValue", "success", "delete", "error"]);

watch(
  () => props.modelValue,
  (newVal) => {
    fileList.value = newVal.map((item) => {
      return typeof item === "string" ? { url: item } : item;
    });
  },
  { immediate: true }
);
/**
 * 文件选择后处理
 */
const handleAfterRead = async (event) => {
  const file = Array.isArray(event.file) ? event.file[0] : event.file;
  uploading.value = true;
  progress.value = 0;
  try {
    const uploadFiles = Array.isArray(file) ? file : [file];
    const results = await Promise.all(
      uploadFiles.map((file) => {
        return $uploadFile({
          filePath: file.url,
          name: "file",
          onProgress(e) {
            progress.value = e.progress;
          },
        });
      })
    );
    const newFiles = results.map((res) => ({
      url: res.data.url,
      name: res.data.name,
      status: "success",
    }));
    fileList.value = [...fileList.value, ...newFiles];
    emit("update:modelValue", fileList.value);
    emit("success", newFiles);
    Toast(t("成功"));
  } catch (error) {
    emit("error", error);
    Toast(t("失败"));
  } finally {
    uploading.value = false;
  }
};

const handleDelete = (event) => {
  const { index } = event;
  const deletedFile = fileList.value[index];
  fileList.value.splice(index, 1);
  progress.value = 0;
  emit("update:modelValue", fileList.value);
  emit("delete", deletedFile);
};

defineExpose({
  clearFiles: () => {
    fileList.value = [];
    progress.value = 0;
    emit("update:modelValue", []);
  },
});
</script>

<style lang="less" scoped>
.video-uploader {
  padding: 10rpx;

  .upload-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 150rpx;
    height: 150rpx;
    border: 1px dashed #c0c4cc;
    border-radius: 8rpx;
    background-color: #f5f7fa;

    .upload-text {
      margin-top: 10rpx;
      font-size: 24rpx;
      color: #909399;
    }
  }

  .preview {
    margin-top: 20rpx;

    .preview-video {
      width: 100%;
      max-height: 200rpx;
      border-radius: 12rpx;
      background-color: #000;
    }
  }
}
</style>