<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { router } from '@inertiajs/vue3';

const isLoading = ref(false);
const progress = ref(0);
let progressTimer: number | undefined;
let hideTimer: number | undefined;

function startLoading() {
    clearTimeout(hideTimer);
    clearInterval(progressTimer);
    isLoading.value = true;
    progress.value = 5;

    // Simulate progress ticking up to ~85% while waiting
    progressTimer = window.setInterval(() => {
        if (progress.value < 85) {
            progress.value += Math.random() * 8;
            if (progress.value > 85) progress.value = 85;
        }
    }, 200);
}

function stopLoading() {
    clearInterval(progressTimer);
    progress.value = 100;
    hideTimer = window.setTimeout(() => {
        isLoading.value = false;
        progress.value = 0;
    }, 350);
}

let offStart: (() => void) | undefined;
let offFinish: (() => void) | undefined;

onMounted(() => {
    offStart = router.on('start', startLoading);
    offFinish = router.on('finish', stopLoading);
});

onUnmounted(() => {
    offStart?.();
    offFinish?.();
    clearTimeout(hideTimer);
    clearInterval(progressTimer);
});
</script>

<template>
    <transition name="app-loading-fade">
        <div v-if="isLoading" class="app-loading-overlay" aria-hidden="true">
            <div class="al-bar" :style="{ width: progress + '%' }"></div>
            <div class="al-spinner">
                <div class="al-ring"></div>
                <div class="al-brand">Beti<span>X</span></div>
            </div>
        </div>
    </transition>
</template>

<style scoped>
.app-loading-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: rgba(5, 5, 5, 0.75);
    backdrop-filter: blur(4px);
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.al-bar {
    position: absolute;
    top: 0;
    left: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--primary, #df006a), #ff8800);
    border-radius: 0 2px 2px 0;
    transition: width 0.2s ease;
    box-shadow: 0 0 12px var(--primary, #df006a);
}

.al-spinner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
}

.al-ring {
    width: 52px;
    height: 52px;
    border: 3px solid rgba(255, 255, 255, 0.08);
    border-top-color: var(--primary, #df006a);
    border-radius: 50%;
    animation: al-spin 0.75s linear infinite;
}

.al-brand {
    font-size: 1.3rem;
    font-weight: 900;
    color: #fff;
    letter-spacing: 0.02em;
}

.al-brand span {
    color: var(--primary, #df006a);
}

@keyframes al-spin {
    to { transform: rotate(360deg); }
}

/* Fade transition */
.app-loading-fade-enter-active,
.app-loading-fade-leave-active {
    transition: opacity 0.25s ease;
}
.app-loading-fade-enter-from,
.app-loading-fade-leave-to {
    opacity: 0;
}
</style>
