<template>
    <div class="pointer-events-none fixed top-4 left-1/2 z-[9999] w-full max-w-md -translate-x-1/2 px-4">
        <transition-group name="alert-fade" tag="div"
            class="pointer-events-none flex w-full flex-col items-stretch gap-2"
            :class="alerts.length > 3 ? 'max-h-[80vh] overflow-y-auto' : ''"
            aria-live="polite" role="status">
            <div v-for="(alert, index) in alerts" :key="alert.id"
                class="pointer-events-auto relative flex items-start gap-3 rounded-lg bg-theme-950/95 p-3.5 pr-2 shadow-lg backdrop-blur-sm"
                :class="meta(alert.type).border">
                <i v-if="meta(alert.type).icon" class="ph mt-0.5 flex-shrink-0" :class="[meta(alert.type).icon, meta(alert.type).iconColor]"></i>

                <div class="flex min-w-0 flex-1 flex-col gap-0.5">
                    <strong v-if="alert.title" class="text-sm font-semibold" :class="meta(alert.type).title">{{ alert.title }}</strong>
                    <p v-if="alert.message" class="break-words text-sm leading-5" :class="meta(alert.type).body">{{ alert.message }}</p>
                </div>

                <button @click="dismiss(alert)" aria-label="Dismiss"
                    class="flex-shrink-0 rounded-md p-1 text-theme-400 transition-colors hover:bg-theme-800/50 hover:text-theme-200">
                    <span class="ph ph-x text-lg"></span>
                </button>

                <div class="progress-bar absolute bottom-0 left-0 h-0.5 origin-left rounded-full"
                    :class="meta(alert.type).bar"
                    :style="{ animationDuration: (alert.ttl || 5000) + 'ms' }"></div>
            </div>
        </transition-group>
    </div>
</template>

<script>
export default {
    name: 'alert',
    computed: {
        alerts() {
            return this.$root.alerts || [];
        },
    },
    methods: {
        meta(type) {
            const map = {
                error: {
                    border: 'border border-rose-500/40',
                    icon: 'ph-warning-circle',
                    iconColor: 'text-rose-400',
                    title: 'text-rose-300',
                    body: 'text-rose-200/80',
                    bar: 'bg-rose-500',
                },
                success: {
                    border: 'border border-green-500/40',
                    icon: 'ph-check-circle',
                    iconColor: 'text-green-400',
                    title: 'text-green-300',
                    body: 'text-green-200/80',
                    bar: 'bg-green-500',
                },
                warning: {
                    border: 'border border-amber-500/40',
                    icon: 'ph-warning',
                    iconColor: 'text-amber-400',
                    title: 'text-amber-300',
                    body: 'text-amber-200/80',
                    bar: 'bg-amber-500',
                },
                info: {
                    border: 'border border-brand-500/40',
                    icon: 'ph-info',
                    iconColor: 'text-brand-400',
                    title: 'text-brand-300',
                    body: 'text-theme-300',
                    bar: 'bg-brand-400',
                },
            };
            return map[type] || {
                border: 'border border-theme-800',
                icon: 'ph-info',
                iconColor: 'text-theme-400',
                title: 'text-theme-200',
                body: 'text-theme-300',
                bar: 'bg-theme-600',
            };
        },
        dismiss(alert) {
            const index = this.alerts.indexOf(alert);
            if (index !== -1) {
                if (alert.timeoutId) clearTimeout(alert.timeoutId);
                this.alerts.splice(index, 1);
            }
        },
    },
};
</script>

<style>
/* Stacking + enter/leave/move transitions */
.alert-fade-enter-active,
.alert-fade-leave-active {
    transition: opacity 0.25s ease, transform 0.25s ease, margin 0.25s ease;
}

.alert-fade-enter-from,
.alert-fade-leave-to {
    opacity: 0;
    transform: translateY(-12px) scale(0.98);
}

.alert-fade-leave-active {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}

.alert-fade-move {
    transition: transform 0.25s ease;
}

/* Auto-dismiss progress */
.progress-bar {
    animation-name: progress;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
}

@keyframes progress {
    0% {
        transform: scaleX(1);
        opacity: 1;
    }

    85% {
        opacity: 1;
    }

    100% {
        transform: scaleX(0);
        opacity: 0;
    }
}
</style>
