<template>
    <text class="number-scroll">{{ displayValue }}</text>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';


const props = defineProps({
    value: {
        type: Number,
        default: 0
    },
    duration: {
        type: Number,
        default: 1000
    },
})
const displayValue = ref('0')
const encipherAmount = (value, type = 0) => {
    if (value != "") {
        if (type == 0) {
            return Math.floor(value)?.toString()?.replace(/\d(?=(\d{3})+\.)/g, "$&,");
        }
        if (type == 1) {
            return (Math.floor(value * 100) / 100)?.toFixed(2);
        }
        if (type == 3) {
            return (isNaN(value) ? 0 : value)?.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, "$&,");
        }
    }
    return '0';
};
const animateNumber = (start, end, duration) => {
    if (start > end) {
        displayValue.value = encipherAmount(end, 3)
        return
    }
    const startTime = Date.now()

    const update = (currentTime) => {
        const elapsed = currentTime - startTime
        const progress = Math.min(elapsed / duration, 1)

        displayValue.value = encipherAmount(Math.floor(start + (end - start) * progress), 3)

        if (progress < 1) {
            setTimeout(() => {
                update(Date.now())
            }, 16.6);
        } else {
            displayValue.value = encipherAmount(end, 3)
        }
    }

    setTimeout(() => {
        update(Date.now())
    }, 16.6);
}

watch(() => props.value, (newValue, oldValue) => {
    animateNumber(oldValue, newValue, props.duration)
})

onMounted(() => {
    displayValue.value = encipherAmount(props.value, 3)
})
</script>
<style lang="scss" scoped>
.number-scroll {
    display: inline-block;
    transition: all 0.3s ease;
}
</style>