<template>
    <div>
        <el-upload
            class="upload-demo"
            :id="uuid"
            action="#"
            :multiple="false"
            :disabled="self_disabled"
            :show-file-list="false"
            :http-request="handleHttpUpload"
            :before-upload="beforeUpload"
            :on-success="uploadSuccess"
            :on-error="uploadError"
            :limit="1"
            :accept="fileType.join(',')"
        >
            <!-- disabled -->
            <el-input v-model="videoShowUrl" style="width: 414px" @click.stop @input="handleInput" disabled>
                <template #prepend
                    ><el-icon :size="20" style="cursor: pointer"><FolderAdd /></el-icon
                ></template>
            </el-input>
        </el-upload>
        <div class="el-upload__tip">
            <slot name="tip"></slot>
        </div>
    </div>
</template>

<script setup lang="ts" name="UploadVideo">
// Edit, ZoomIn, Delete,Plus
import { FolderAdd } from "@element-plus/icons-vue";
import { ref, computed, inject } from "vue";
import { generateUUID } from "@/utils";
import { uploadVideo } from "@/api/modules/upload";
import { ElNotification, formContextKey, formItemContextKey } from "element-plus";
import type { UploadProps, UploadRequestOptions } from "element-plus";

interface UploadFileProps {
    videoUrl: string; // 图片地址 ==> 必传
    api?: (params: any) => Promise<any>; // 上传图片的 api 方法，一般项目上传都是同一个 api 方法，在组件里直接引入即可 ==> 非必传
    width?: string;
    disabled?: boolean; // 是否禁用上传组件 ==> 非必传（默认为 false）
    fileSize?: number; //视频大小限制 ==> 非必传（默认为 5M）
    fileType?: any[]; //视频类型限制 ==> 非必传（默认为[".mp4", ".avi", ".mov"]）
    borderRadius?: string; // 组件边框圆角 ==> 非必传（默认为 8px）
}
const videoShowUrl = ref(null);
// 接受父组件参数
const props = withDefaults(defineProps<UploadFileProps>(), {
    videoUrl: "",
    disabled: false,
    fileSize: 200,
    width: "400px",
    fileType: () => [".mp4", ".avi", ".mov", "video/mp4", "video/mov", "video/avi"],
    borderRadius: "8px"
});
const $router = useRouter();
const routerValueName: string = $router.currentRoute.value.name as string;
const routerObj: any = {
    articleEditIndex: "article",
    productEditIndex: "product",
    videoListIndex: "video"
};
const routerName = ref(routerObj[routerValueName]);

// 生成组件唯一id
const uuid = ref("id-" + generateUUID());

// 获取 el-form 组件上下文
const formContext = inject(formContextKey, void 0);
// 获取 el-form-item 组件上下文
const formItemContext = inject(formItemContextKey, void 0);
// 判断是否禁用上传和删除
const self_disabled = computed(() => {
    return props.disabled || formContext?.disabled;
});
/**
 * @description 视频上传
 * @param options upload 所有配置项
 * */
interface UploadEmits {
    (e: "update:videoUrl", value: string): void;
}
const emit = defineEmits<UploadEmits>();
const handleHttpUpload = async (options: UploadRequestOptions) => {
    let formData = new FormData();
    formData.append("video", options.file);
    try {
        const api = props.api ?? uploadVideo;
        const { data } = await api(formData, routerName.value);
        emit("update:videoUrl", data.path);
        // 调用 el-form 内部的校验方法（可自动校验）
        formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
    } catch (error) {
        options.onError(error as any);
    }
};

const handleInput = () => {
    console.log("会触发吗");
};

/**
 * @description 文件上传之前判断
 * @param rawFile 选择的文件
 * */
const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
    const videoSize = rawFile.size / 1024 / 1024 < props.fileSize;
    const videoType = props.fileType.includes(rawFile.type as any);
    if (!videoType)
        ElNotification({
            title: "温馨提示",
            message: "上传视频不符合所需的格式！",
            type: "warning"
        });
    if (!videoSize)
        setTimeout(() => {
            ElNotification({
                title: "温馨提示",
                message: `上传视频大小不能超过 ${props.fileSize}M！`,
                type: "warning"
            });
        }, 0);
    return videoType && videoSize;
};

/**
 * @description 视频上传成功
 * */
const uploadSuccess = () => {
    ElNotification({
        title: "温馨提示",
        message: "视频上传成功！",
        type: "success"
    });
};

/**
 * @description 视频上传错误
 * */
const uploadError = () => {
    ElNotification({
        title: "温馨提示",
        message: "视频上传失败，请您重新上传！",
        type: "error"
    });
};
watch(
    () => props.videoUrl,
    (newVal: any) => {
        videoShowUrl.value = newVal;
    }
);
</script>

<style scoped lang="scss">
.el-upload__tip {
    line-height: 18px;
    text-align: center;
}
</style>
