<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { Head, Link, router } from '@inertiajs/vue3'
import { debounce } from 'lodash'
import AdminLayout from '@/Layouts/AdminLayout.vue'
import {
    ClipboardDocumentListIcon,
    MagnifyingGlassIcon,
    CheckCircleIcon,
    XCircleIcon,
    ExclamationTriangleIcon,
    ArrowDownTrayIcon,
    XMarkIcon,
    EyeIcon,
    ChevronDownIcon,
    ChevronUpIcon,
    ClockIcon,
    UserIcon,
    BoltIcon,
    ShieldCheckIcon,
} from '@heroicons/vue/24/outline'

const props = defineProps({
    logs: Object,
    filters: Object,
    actions_distinct: { type: Array, default: () => [] },
    target_types_distinct: { type: Array, default: () => [] },
    users_active: { type: Array, default: () => [] },
    outcomes: { type: Array, default: () => ['success', 'failure', 'partial'] },
    per_page_options: { type: Array, default: () => [20, 50, 100, 200] },
    stats_top: { type: Object, default: () => ({ total: 0, last_24h: 0, failure_rate_24h: 0, retention_days: 90 }) },
    export_hard_cap: { type: Number, default: 100000 },
})

// Filtre state
const action = ref(props.filters.action ?? '')
const outcome = ref(props.filters.outcome ?? '')
const userId = ref(props.filters.user_id ?? '')
const targetType = ref(props.filters.target_type ?? '')
const ipAddress = ref(props.filters.ip_address ?? '')
const dateFrom = ref(props.filters.date_from ?? '')
const dateTo = ref(props.filters.date_to ?? '')
const search = ref(props.filters.search ?? '')
const perPage = ref(props.filters.per_page ?? 50)

// Inline expand
const expandedRows = ref(new Set())
const toggleExpand = (id) => {
    if (expandedRows.value.has(id)) {
        expandedRows.value.delete(id)
    } else {
        expandedRows.value.add(id)
    }
    // reactivity için yeni Set
    expandedRows.value = new Set(expandedRows.value)
}

// Sparkline — son 24h
const sparkline = ref([])
const sparkLoading = ref(false)
const loadStats = async () => {
    sparkLoading.value = true
    try {
        const resp = await fetch(route('admin.audit.stats'), { headers: { Accept: 'application/json' } })
        if (resp.ok) {
            const data = await resp.json()
            sparkline.value = (data.actions_last_24h || []).map((b) => b.count)
        }
    } catch (e) {
        // sessiz — sparkline opsiyonel
    } finally {
        sparkLoading.value = false
    }
}

onMounted(loadStats)

// Sparkline SVG path — basit polyline
const sparkPath = computed(() => {
    const arr = sparkline.value
    if (!arr.length) return ''
    const max = Math.max(...arr, 1)
    const w = 320
    const h = 40
    const step = arr.length > 1 ? w / (arr.length - 1) : w
    return arr
        .map((v, i) => {
            const x = i * step
            const y = h - (v / max) * h
            return `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`
        })
        .join(' ')
})

const sparkMax = computed(() => (sparkline.value.length ? Math.max(...sparkline.value) : 0))

// Query rebuild
const buildParams = () => ({
    action: action.value || undefined,
    outcome: outcome.value || undefined,
    user_id: userId.value || undefined,
    target_type: targetType.value || undefined,
    ip_address: ipAddress.value || undefined,
    date_from: dateFrom.value || undefined,
    date_to: dateTo.value || undefined,
    search: search.value || undefined,
    per_page: perPage.value !== 50 ? perPage.value : undefined,
})

const refresh = () => {
    router.get(route('admin.audit.index'), buildParams(), {
        preserveState: true,
        preserveScroll: true,
        replace: true,
    })
}

const debouncedRefresh = debounce(refresh, 300)

const clearFilters = () => {
    action.value = ''
    outcome.value = ''
    userId.value = ''
    targetType.value = ''
    ipAddress.value = ''
    dateFrom.value = ''
    dateTo.value = ''
    search.value = ''
    perPage.value = 50
    refresh()
}

const hasActiveFilters = computed(
    () => action.value || outcome.value || userId.value || targetType.value || ipAddress.value || dateFrom.value || dateTo.value || search.value
)

// Export URL — current filters
const exportUrl = (format) => {
    const params = new URLSearchParams()
    Object.entries(buildParams()).forEach(([k, v]) => {
        if (v !== undefined && v !== '') params.set(k, v)
    })
    const name = format === 'json' ? 'admin.audit.export.json' : 'admin.audit.export.csv'
    const qs = params.toString()
    return route(name) + (qs ? '?' + qs : '')
}

// Watchers — sayısal/text inputlar debounce, select'ler instant
watch(action, debouncedRefresh)
watch(search, debouncedRefresh)
watch(ipAddress, debouncedRefresh)
watch(targetType, debouncedRefresh)
watch(outcome, refresh)
watch(userId, refresh)
watch(dateFrom, refresh)
watch(dateTo, refresh)
watch(perPage, refresh)

// Helpers
const outcomeIcon = (o) => {
    if (o === 'success') return { icon: CheckCircleIcon, class: 'text-emerald-500' }
    if (o === 'failure') return { icon: XCircleIcon, class: 'text-red-500' }
    return { icon: ExclamationTriangleIcon, class: 'text-amber-500' }
}

const outcomeBadge = (o) => {
    if (o === 'success') return 'bg-emerald-50 text-emerald-700 ring-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:ring-emerald-700'
    if (o === 'failure') return 'bg-red-50 text-red-700 ring-red-200 dark:bg-red-900/30 dark:text-red-300 dark:ring-red-700'
    return 'bg-amber-50 text-amber-700 ring-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:ring-amber-700'
}

// Aksiyon prefix'e göre renk — account.*, db.*, dns.* gibi ailelere göre
const actionBadge = (a) => {
    if (!a) return 'bg-slate-100 text-slate-700 ring-slate-200'
    const prefix = a.split('.')[0]
    const palette = {
        account: 'bg-indigo-50 text-indigo-700 ring-indigo-200',
        backup: 'bg-cyan-50 text-cyan-700 ring-cyan-200',
        db: 'bg-purple-50 text-purple-700 ring-purple-200',
        dns: 'bg-teal-50 text-teal-700 ring-teal-200',
        mail: 'bg-sky-50 text-sky-700 ring-sky-200',
        ssl: 'bg-emerald-50 text-emerald-700 ring-emerald-200',
        apache: 'bg-orange-50 text-orange-700 ring-orange-200',
        fpm: 'bg-yellow-50 text-yellow-700 ring-yellow-200',
        cron: 'bg-fuchsia-50 text-fuchsia-700 ring-fuchsia-200',
        process: 'bg-rose-50 text-rose-700 ring-rose-200',
    }
    return palette[prefix] || 'bg-slate-100 text-slate-700 ring-slate-200'
}

const formatDate = (dt) => {
    if (!dt) return '—'
    return new Date(dt).toLocaleString('tr-TR', { dateStyle: 'short', timeStyle: 'medium' })
}

const relativeTime = (dt) => {
    if (!dt) return ''
    const diff = (Date.now() - new Date(dt).getTime()) / 1000
    if (diff < 60) return `${Math.floor(diff)}s önce`
    if (diff < 3600) return `${Math.floor(diff / 60)}dk önce`
    if (diff < 86400) return `${Math.floor(diff / 3600)}sa önce`
    return `${Math.floor(diff / 86400)}g önce`
}

const shortTarget = (t) => {
    if (!t) return ''
    // Polymorphic class name — son segment
    return t.split('\\').pop()
}

const metadataPreview = (raw) => {
    if (!raw) return ''
    try {
        const obj = typeof raw === 'string' ? JSON.parse(raw) : raw
        const str = JSON.stringify(obj)
        return str.length > 80 ? str.slice(0, 80) + '…' : str
    } catch (e) {
        const str = String(raw)
        return str.length > 80 ? str.slice(0, 80) + '…' : str
    }
}

const metadataPretty = (raw) => {
    if (!raw) return null
    try {
        const obj = typeof raw === 'string' ? JSON.parse(raw) : raw
        return JSON.stringify(obj, null, 2)
    } catch (e) {
        return String(raw)
    }
}

// Export tıklandığında ön-uyarı (hard cap warning)
const exportClicked = (format, e) => {
    if (props.logs.total > props.export_hard_cap) {
        e.preventDefault()
        alert(`Filtre ${props.logs.total} kayıt seçti, izin verilen maksimum ${props.export_hard_cap}. Lütfen tarih aralığını daraltın.`)
    }
}
</script>

<template>
    <Head title="Denetim Kaydı" />

    <AdminLayout>
        <template #header>Denetim Kaydı</template>

        <!-- KVKK info -->
        <div class="mb-4 rounded-lg border border-indigo-200 bg-indigo-50 dark:border-indigo-800 dark:bg-indigo-900/30 p-3 text-sm text-indigo-900 dark:text-indigo-200">
            <ShieldCheckIcon class="mr-1 inline h-4 w-4" />
            KVKK uyumlu — PII alanları maskelenir. Retention <strong>{{ stats_top.retention_days }}</strong> gün, <code class="rounded bg-indigo-100 dark:bg-indigo-800/60 px-1">php artisan onox:prune</code> ile otomatik temizlenir.
        </div>

        <!-- Top metric cards -->
        <div class="mb-4 grid grid-cols-2 gap-3 sm:grid-cols-4">
            <div class="rounded-xl border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800 p-4">
                <div class="flex items-center gap-2 text-xs text-slate-500 dark:text-slate-400">
                    <ClipboardDocumentListIcon class="h-4 w-4" /> Toplam Kayıt
                </div>
                <div class="mt-1 text-2xl font-semibold text-slate-900 dark:text-slate-100">{{ stats_top.total.toLocaleString('tr-TR') }}</div>
            </div>
            <div class="rounded-xl border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800 p-4">
                <div class="flex items-center gap-2 text-xs text-slate-500 dark:text-slate-400">
                    <ClockIcon class="h-4 w-4" /> Son 24 Saat
                </div>
                <div class="mt-1 text-2xl font-semibold text-slate-900 dark:text-slate-100">{{ stats_top.last_24h.toLocaleString('tr-TR') }}</div>
            </div>
            <div class="rounded-xl border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800 p-4">
                <div class="flex items-center gap-2 text-xs text-slate-500 dark:text-slate-400">
                    <BoltIcon class="h-4 w-4" /> Hata Oranı 24h
                </div>
                <div
                    class="mt-1 text-2xl font-semibold"
                    :class="stats_top.failure_rate_24h > 5 ? 'text-red-600' : 'text-emerald-600'"
                >
                    %{{ stats_top.failure_rate_24h }}
                </div>
            </div>
            <div class="rounded-xl border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800 p-4">
                <div class="flex items-center gap-2 text-xs text-slate-500 dark:text-slate-400">
                    <ShieldCheckIcon class="h-4 w-4" /> Retention
                </div>
                <div class="mt-1 text-2xl font-semibold text-slate-900 dark:text-slate-100">{{ stats_top.retention_days }} <span class="text-sm font-normal text-slate-500">gün</span></div>
            </div>
        </div>

        <!-- Sparkline -->
        <div class="mb-4 rounded-xl border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800 p-4">
            <div class="mb-2 flex items-center justify-between">
                <div class="text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">Son 24 saat aksiyon hacmi</div>
                <div class="text-xs text-slate-400">tepe: {{ sparkMax }}</div>
            </div>
            <svg v-if="sparkline.length" viewBox="0 0 320 40" class="h-10 w-full" preserveAspectRatio="none">
                <path :d="sparkPath" stroke="#6366f1" stroke-width="1.5" fill="none" />
            </svg>
            <div v-else class="h-10 flex items-center text-xs text-slate-400">{{ sparkLoading ? 'yükleniyor…' : 'veri yok' }}</div>
        </div>

        <!-- Filter toolbar -->
        <div class="mb-4 grid grid-cols-1 gap-3 rounded-xl border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800 p-4 shadow-sm sm:grid-cols-2 lg:grid-cols-6">
            <div class="relative lg:col-span-2">
                <MagnifyingGlassIcon class="absolute left-3 top-2.5 h-4 w-4 text-slate-400" />
                <input
                    v-model="search"
                    type="text"
                    placeholder="action / metadata / hata mesajı ara…"
                    class="w-full rounded-lg border border-slate-200 bg-white dark:border-slate-600 dark:bg-slate-900 py-2 pl-9 pr-3 text-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
                />
            </div>

            <input
                v-model="action"
                type="text"
                list="actions-list"
                placeholder="aksiyon (account.created…)"
                class="rounded-lg border border-slate-200 bg-white dark:border-slate-600 dark:bg-slate-900 px-3 py-2 text-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
            />
            <datalist id="actions-list">
                <option v-for="a in actions_distinct" :key="a.action" :value="a.action">{{ a.action }} ({{ a.cnt }})</option>
            </datalist>

            <select
                v-model="outcome"
                class="rounded-lg border border-slate-200 bg-white dark:border-slate-600 dark:bg-slate-900 px-3 py-2 text-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
            >
                <option value="">Tüm Sonuçlar</option>
                <option v-for="o in outcomes" :key="o" :value="o">{{ o === 'success' ? 'Başarılı' : o === 'failure' ? 'Başarısız' : 'Kısmi' }}</option>
            </select>

            <select
                v-model="userId"
                class="rounded-lg border border-slate-200 bg-white dark:border-slate-600 dark:bg-slate-900 px-3 py-2 text-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
            >
                <option value="">Tüm Kullanıcılar</option>
                <option v-for="u in users_active" :key="u.id" :value="u.id">
                    {{ u.name || u.email }} ({{ u.cnt }})
                </option>
            </select>

            <select
                v-model="targetType"
                class="rounded-lg border border-slate-200 bg-white dark:border-slate-600 dark:bg-slate-900 px-3 py-2 text-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
            >
                <option value="">Tüm Hedef Tipleri</option>
                <option v-for="t in target_types_distinct" :key="t.target_type" :value="t.target_type">
                    {{ shortTarget(t.target_type) }} ({{ t.cnt }})
                </option>
            </select>

            <input
                v-model="ipAddress"
                type="text"
                placeholder="IP ara…"
                class="rounded-lg border border-slate-200 bg-white dark:border-slate-600 dark:bg-slate-900 px-3 py-2 text-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
            />

            <input
                v-model="dateFrom"
                type="date"
                class="rounded-lg border border-slate-200 bg-white dark:border-slate-600 dark:bg-slate-900 px-3 py-2 text-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
            />
            <input
                v-model="dateTo"
                type="date"
                class="rounded-lg border border-slate-200 bg-white dark:border-slate-600 dark:bg-slate-900 px-3 py-2 text-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
            />

            <select
                v-model.number="perPage"
                class="rounded-lg border border-slate-200 bg-white dark:border-slate-600 dark:bg-slate-900 px-3 py-2 text-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
            >
                <option v-for="p in per_page_options" :key="p" :value="p">{{ p }}/sayfa</option>
            </select>

            <div class="lg:col-span-6 flex flex-wrap items-center justify-between gap-3 pt-2 border-t border-slate-100 dark:border-slate-700">
                <div class="text-xs text-slate-500 dark:text-slate-400">
                    <strong>{{ logs.total }}</strong> kayıt eşleşti
                    <span class="text-slate-400">/ toplam {{ stats_top.total }}</span>
                </div>
                <div class="flex gap-2">
                    <button
                        v-if="hasActiveFilters"
                        @click="clearFilters"
                        class="inline-flex items-center gap-1 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 px-3 py-1.5 text-xs font-medium text-slate-700 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700"
                    >
                        <XMarkIcon class="h-3.5 w-3.5" /> Filtreyi temizle
                    </button>
                    <a
                        :href="exportUrl('csv')"
                        @click="(e) => exportClicked('csv', e)"
                        class="inline-flex items-center gap-1.5 rounded-lg bg-emerald-600 px-4 py-1.5 text-xs font-semibold text-white shadow-sm hover:bg-emerald-700"
                    >
                        <ArrowDownTrayIcon class="h-3.5 w-3.5" /> CSV İndir
                    </a>
                    <a
                        :href="exportUrl('json')"
                        @click="(e) => exportClicked('json', e)"
                        class="inline-flex items-center gap-1.5 rounded-lg bg-indigo-600 px-4 py-1.5 text-xs font-semibold text-white shadow-sm hover:bg-indigo-700"
                    >
                        <ArrowDownTrayIcon class="h-3.5 w-3.5" /> JSON İndir
                    </a>
                </div>
            </div>
        </div>

        <!-- Empty state -->
        <div v-if="logs.data.length === 0" class="rounded-xl border border-dashed border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-800 p-12 text-center">
            <ClipboardDocumentListIcon class="mx-auto h-14 w-14 text-slate-300" />
            <h3 class="mt-3 text-lg font-semibold text-slate-900 dark:text-slate-100">Eşleşen kayıt yok</h3>
            <p class="mt-1 text-sm text-slate-500">Filtreyi gevşetmeyi deneyin.</p>
        </div>

        <!-- Table -->
        <div v-else class="overflow-hidden rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 shadow-sm">
            <table class="min-w-full divide-y divide-slate-200 dark:divide-slate-700">
                <thead class="bg-slate-50 dark:bg-slate-900/40">
                    <tr>
                        <th class="w-10"></th>
                        <th class="px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">Zaman</th>
                        <th class="px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">Kullanıcı</th>
                        <th class="px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">Aksiyon</th>
                        <th class="px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">Hedef</th>
                        <th class="px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">IP</th>
                        <th class="px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">Sonuç</th>
                        <th class="px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">Metadata</th>
                        <th class="px-3 py-3"></th>
                    </tr>
                </thead>
                <tbody class="divide-y divide-slate-100 dark:divide-slate-700">
                    <template v-for="log in logs.data" :key="log.id">
                        <tr class="hover:bg-slate-50 dark:hover:bg-slate-700/30">
                            <td class="px-2 py-2 align-top">
                                <button @click="toggleExpand(log.id)" class="rounded p-1 hover:bg-slate-100 dark:hover:bg-slate-700" :aria-label="expandedRows.has(log.id) ? 'Daralt' : 'Genişlet'">
                                    <ChevronUpIcon v-if="expandedRows.has(log.id)" class="h-4 w-4 text-slate-500" />
                                    <ChevronDownIcon v-else class="h-4 w-4 text-slate-500" />
                                </button>
                            </td>
                            <td class="whitespace-nowrap px-3 py-3 align-top text-xs">
                                <div class="text-slate-700 dark:text-slate-300">{{ formatDate(log.created_at) }}</div>
                                <div class="text-slate-400">{{ relativeTime(log.created_at) }}</div>
                            </td>
                            <td class="px-3 py-3 align-top text-sm">
                                <template v-if="log.user_name || log.user_email">
                                    <div class="font-medium text-slate-900 dark:text-slate-100">{{ log.user_name || log.user_email }}</div>
                                    <div v-if="log.user_email && log.user_name" class="text-xs text-slate-500">{{ log.user_email }}</div>
                                </template>
                                <span v-else class="inline-flex items-center gap-1 text-xs italic text-slate-400">
                                    <UserIcon class="h-3 w-3" /> sistem
                                </span>
                            </td>
                            <td class="px-3 py-3 align-top">
                                <span :class="['inline-flex items-center rounded-full px-2 py-0.5 font-mono text-xs ring-1 ring-inset', actionBadge(log.action)]">
                                    {{ log.action }}
                                </span>
                            </td>
                            <td class="px-3 py-3 align-top text-xs text-slate-600 dark:text-slate-300">
                                <template v-if="log.target_type">
                                    <div>{{ shortTarget(log.target_type) }}</div>
                                    <div v-if="log.target_id" class="text-slate-400">#{{ log.target_id }}</div>
                                </template>
                                <span v-else class="text-slate-400">—</span>
                            </td>
                            <td class="whitespace-nowrap px-3 py-3 align-top font-mono text-xs text-slate-500">
                                {{ log.ip_address || '—' }}
                            </td>
                            <td class="px-3 py-3 align-top">
                                <span :class="['inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium ring-1 ring-inset', outcomeBadge(log.outcome)]">
                                    <component :is="outcomeIcon(log.outcome).icon" class="h-3 w-3" />
                                    {{ log.outcome }}
                                </span>
                            </td>
                            <td class="px-3 py-3 align-top font-mono text-xs text-slate-500 max-w-xs truncate">
                                {{ metadataPreview(log.metadata) || '—' }}
                            </td>
                            <td class="px-3 py-3 align-top">
                                <Link :href="route('admin.audit.show', log.id)" class="inline-flex items-center gap-1 rounded-md border border-slate-200 dark:border-slate-600 px-2 py-1 text-xs text-slate-700 dark:text-slate-200 hover:bg-slate-50 dark:hover:bg-slate-700">
                                    <EyeIcon class="h-3.5 w-3.5" /> Detay
                                </Link>
                            </td>
                        </tr>
                        <tr v-if="expandedRows.has(log.id)" class="bg-slate-50 dark:bg-slate-900/30">
                            <td colspan="9" class="px-6 py-4">
                                <div class="grid grid-cols-1 gap-3 md:grid-cols-2">
                                    <div v-if="log.metadata">
                                        <div class="mb-1 text-xs font-semibold uppercase text-slate-500">Metadata</div>
                                        <pre class="max-h-64 overflow-auto rounded border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 p-2 text-xs">{{ metadataPretty(log.metadata) }}</pre>
                                    </div>
                                    <div v-if="log.error_message">
                                        <div class="mb-1 text-xs font-semibold uppercase text-red-500">Hata</div>
                                        <pre class="max-h-64 overflow-auto rounded border border-red-200 bg-red-50 p-2 text-xs text-red-900">{{ log.error_message }}</pre>
                                    </div>
                                </div>
                            </td>
                        </tr>
                    </template>
                </tbody>
            </table>

            <div v-if="logs.last_page > 1" class="flex flex-wrap items-center justify-between border-t border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-900/40 px-4 py-3 gap-2">
                <div class="text-sm text-slate-600 dark:text-slate-400">
                    {{ logs.from }}-{{ logs.to }} / {{ logs.total }}
                </div>
                <div class="flex flex-wrap gap-1">
                    <Link
                        v-for="link in logs.links"
                        :key="link.label"
                        :href="link.url || '#'"
                        :class="[
                            'rounded px-3 py-1 text-sm',
                            link.active ? 'bg-indigo-600 text-white' : 'text-slate-600 dark:text-slate-300 hover:bg-white dark:hover:bg-slate-700',
                            !link.url && 'cursor-not-allowed opacity-40',
                        ]"
                        preserve-scroll
                        v-html="link.label"
                    />
                </div>
            </div>
        </div>
    </AdminLayout>
</template>
