import { computed, ref } from "vue";
import type { UploadProgressSnapshot } from "../../../services/ApiHttpClient";

export function useUploadProgress() {
    const active = ref(false);
    const completed = ref(false);
    const failed = ref(false);
    const fileCount = ref(0);
    const loaded = ref(0);
    const total = ref(0);
    const percent = ref(0);
    let resetTimer: ReturnType<typeof window.setTimeout> | undefined;

    const visible = computed(() => active.value || completed.value || failed.value);
    const progressValue = computed(() => percent.value / 100);
    const statusText = computed(() => {
        if (failed.value) {
            return "上传失败";
        }
        if (completed.value) {
            return "上传完成";
        }
        return "上传中";
    });
    const detailText = computed(() => {
        const parts = [`${Math.max(fileCount.value, 1)} 个文件`];
        if (total.value > 0) {
            parts.push(`${formatUploadSize(loaded.value)} / ${formatUploadSize(total.value)}`);
        } else if (loaded.value > 0) {
            parts.push(formatUploadSize(loaded.value));
        } else {
            parts.push("等待传输");
        }
        parts.push(`${percent.value}%`);
        return parts.join(" · ");
    });

    function start(count = 1) {
        clearResetTimer();
        active.value = true;
        completed.value = false;
        failed.value = false;
        fileCount.value = Math.max(count, 1);
        loaded.value = 0;
        total.value = 0;
        percent.value = 0;
    }

    function update(progress: UploadProgressSnapshot) {
        loaded.value = progress.loaded;
        total.value = progress.total;
        percent.value = progress.lengthComputable ? progress.percent : Math.max(percent.value, 12);
    }

    function finish() {
        active.value = false;
        completed.value = true;
        failed.value = false;
        percent.value = 100;
        resetTimer = window.setTimeout(reset, 1200);
    }

    function fail() {
        active.value = false;
        completed.value = false;
        failed.value = true;
        percent.value = Math.max(percent.value, 4);
    }

    function reset() {
        clearResetTimer();
        active.value = false;
        completed.value = false;
        failed.value = false;
        fileCount.value = 0;
        loaded.value = 0;
        total.value = 0;
        percent.value = 0;
    }

    function clearResetTimer() {
        if (resetTimer !== undefined) {
            window.clearTimeout(resetTimer);
            resetTimer = undefined;
        }
    }

    return {
        active,
        completed,
        failed,
        visible,
        progressValue,
        statusText,
        detailText,
        start,
        update,
        finish,
        fail,
        reset,
    };
}

function formatUploadSize(value: number) {
    if (value >= 1024 * 1024) {
        return `${(value / 1024 / 1024).toFixed(1)} MB`;
    }
    if (value >= 1024) {
        return `${(value / 1024).toFixed(1)} KB`;
    }
    return `${Math.max(0, Math.round(value))} B`;
}
评论加载中...