<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue'
import SongEditModal from '@/Components/SongEditModal.vue'
import CcliPasteDialog from '@/Components/CcliPasteDialog.vue'
import { Head, router } from '@inertiajs/vue3'
import axios from 'axios'
import { ref, watch, onMounted } from 'vue'

const songs = ref([])
const meta = ref({ current_page: 1, last_page: 1, per_page: 20, total: 0 })
const search = ref('')
const onlyWithContent = ref(true)
const loading = ref(false)
const deleting = ref(null)
const showDeleteConfirm = ref(false)
const deleteTarget = ref(null)

// Upload state
const isDragging = ref(false)
const uploadError = ref('')
const uploadSuccess = ref('')
const fileInput = ref(null)

// Edit modal state
const showEditModal = ref(false)
const editSongId = ref(null)
const ccliDialogOpen = ref(false)
let debounceTimer = null

// Preview modal state
const previewSong = ref(null)
const previewData = ref(null)
const previewLoading = ref(false)

async function fetchSongs(page = 1) {
    loading.value = true
    try {
        const params = new URLSearchParams({ page, per_page: 20 })
        if (search.value.trim()) {
            params.set('search', search.value.trim())
        }
        params.set('with_content', onlyWithContent.value ? '1' : '0')
        const response = await fetch(`/api/songs?${params}`, {
            headers: {
                Accept: 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
            },
            credentials: 'same-origin',
        })
        if (!response.ok) throw new Error('Fehler beim Laden')
        const json = await response.json()
        songs.value = json.data
        meta.value = json.meta
    } catch (err) {
        console.error('Song fetch error:', err)
    } finally {
        loading.value = false
    }
}

watch(search, () => {
    clearTimeout(debounceTimer)
    debounceTimer = setTimeout(() => fetchSongs(1), 500)
})

watch(onlyWithContent, () => fetchSongs(1))

onMounted(() => fetchSongs())

function goToPage(page) {
    if (page < 1 || page > meta.value.last_page) return
    fetchSongs(page)
}

// Open SongSelect search in a new tab AND open the CCLI import dialog so the user can paste.
function openSongSelectSearch() {
    const query = search.value.trim()
    if (query) {
        window.open(
            `https://songselect.ccli.com/search/results?search=${encodeURIComponent(query)}`,
            '_blank',
            'noopener,noreferrer',
        )
    }
    ccliDialogOpen.value = true
}

function formatDate(value) {
    if (!value) return '–'
    return new Date(value).toLocaleDateString('de-DE', {
        day: '2-digit',
        month: '2-digit',
        year: 'numeric',
    })
}

function formatDateTime(value) {
    if (!value) return '–'
    return new Date(value).toLocaleString('de-DE', {
        day: '2-digit',
        month: '2-digit',
        year: 'numeric',
        hour: '2-digit',
        minute: '2-digit',
    })
}

// --- Actions ---

function confirmDelete(song) {
    deleteTarget.value = song
    showDeleteConfirm.value = true
}

async function deleteSong() {
    if (!deleteTarget.value) return
    deleting.value = deleteTarget.value.id
    try {
        const response = await fetch(`/api/songs/${deleteTarget.value.id}`, {
            method: 'DELETE',
            headers: {
                Accept: 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || '',
            },
            credentials: 'same-origin',
        })
        if (!response.ok) throw new Error('Fehler beim Löschen')
        showDeleteConfirm.value = false
        deleteTarget.value = null
        await fetchSongs(meta.value.current_page)
    } catch (err) {
        console.error('Delete error:', err)
    } finally {
        deleting.value = null
    }
}

function cancelDelete() {
    showDeleteConfirm.value = false
    deleteTarget.value = null
}

function openEditModal(song) {
    editSongId.value = song.id
    showEditModal.value = true
}

function closeEditModal() {
    showEditModal.value = false
    editSongId.value = null
}

function onSongUpdated() {
    fetchSongs(meta.value.current_page)
}

async function openPreview(song) {
    previewSong.value = song
    previewLoading.value = true
    previewData.value = null

    try {
        // Fetch song details to get arrangements
        const songRes = await fetch(`/api/songs/${song.id}`, {
            headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
            credentials: 'same-origin',
        })
        if (!songRes.ok) throw new Error('Song konnte nicht geladen werden')
        const songDetail = await songRes.json()

        const arrangements = songDetail.data?.arrangements || songDetail.arrangements || []
        if (arrangements.length === 0) {
            previewSong.value = null
            previewLoading.value = false
            return
        }

        const defaultArr = arrangements.find(a => a.is_default) || arrangements[0]
        const previewRes = await fetch(`/songs/${song.id}/arrangements/${defaultArr.id}/preview`, {
            headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
            credentials: 'same-origin',
        })
        if (!previewRes.ok) throw new Error('Vorschau konnte nicht geladen werden')
        previewData.value = await previewRes.json()
    } catch (err) {
        console.error('Preview error:', err)
        previewSong.value = null
    } finally {
        previewLoading.value = false
    }
}

function closePreview() {
    previewSong.value = null
    previewData.value = null
}

// Upload handlers (placeholder — T23 will implement parser)
function handleDragOver(e) {
    e.preventDefault()
    isDragging.value = true
}

function handleDragLeave() {
    isDragging.value = false
}

async function handleDrop(e) {
    e.preventDefault()
    isDragging.value = false
    const droppedFiles = Array.from(e.dataTransfer?.files || [])
    if (droppedFiles.length === 0) return
    await uploadProFiles(droppedFiles)
}

function triggerFileInput() {
    fileInput.value?.click()
}

function handleFileSelect() {
    const selectedFiles = Array.from(fileInput.value?.files || [])
    if (fileInput.value) fileInput.value.value = ''
    if (selectedFiles.length === 0) return
    uploadProFiles(selectedFiles)
}

async function uploadProFiles(files) {
    uploadError.value = ''
    loading.value = true
    let successCount = 0
    let errors = []

    for (const file of files) {
        const formData = new FormData()
        formData.append('file', file)

        try {
            await axios.post('/api/songs/import-pro', formData, {
                headers: { 'Content-Type': 'multipart/form-data' },
            })
            successCount++
        } catch (err) {
            const message = err.response?.data?.message || `Fehler bei "${file.name}"`
            errors.push(message)
        }
    }

    if (successCount > 0) {
        await fetchSongs(1)
        uploadSuccess.value = `${successCount} ${successCount === 1 ? 'Song' : 'Songs'} erfolgreich importiert.`
        setTimeout(() => { uploadSuccess.value = '' }, 4000)
    }

    if (errors.length > 0) {
        uploadError.value = errors.join(', ')
        setTimeout(() => { uploadError.value = '' }, 6000)
    }
    loading.value = false
}

// Page range for pagination
function pageRange() {
    const current = meta.value.current_page
    const last = meta.value.last_page
    const delta = 2
    const range = []

    for (let i = Math.max(2, current - delta); i <= Math.min(last - 1, current + delta); i++) {
        range.push(i)
    }

    if (current - delta > 2) range.unshift('...')
    if (current + delta < last - 1) range.push('...')

    range.unshift(1)
    if (last > 1) range.push(last)

    return range
}
</script>

<template>
    <Head title="Song-Datenbank" />

    <AuthenticatedLayout>
        <template #header>
            <div class="flex flex-wrap items-center justify-between gap-3">
                <h2 class="text-xl font-semibold leading-tight text-gray-800">Song-Datenbank</h2>
                <p class="text-sm text-gray-500">Verwalte alle Songs, Übersetzungen und Arrangements.</p>
            </div>
        </template>

        <div class="py-8">
            <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">

                <!-- Upload Area -->
                <div
                    data-testid="song-list-upload-area"
                    class="group relative mb-6 cursor-pointer overflow-hidden rounded-xl border-2 border-dashed transition-all duration-300"
                    :class="isDragging
                        ? 'border-amber-400 bg-amber-50/80 shadow-lg shadow-amber-100/50'
                        : 'border-gray-200 bg-white hover:border-amber-300 hover:bg-amber-50/30'"
                    @dragover="handleDragOver"
                    @dragleave="handleDragLeave"
                    @drop="handleDrop"
                    @click="triggerFileInput"
                >
                    <input
                        data-testid="song-list-file-input"
                        ref="fileInput"
                        type="file"
                        multiple
                        accept=".pro,.zip"
                        class="hidden"
                        @change="handleFileSelect"
                    />

                    <div class="flex flex-col items-center justify-center px-6 py-8">
                        <!-- Upload icon -->
                        <div
                            class="mb-3 flex h-12 w-12 items-center justify-center rounded-xl transition-all duration-300"
                            :class="isDragging
                                ? 'bg-amber-200/80 text-amber-700 scale-110'
                                : 'bg-gray-100 text-gray-400 group-hover:bg-amber-100 group-hover:text-amber-600'"
                        >
                            <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5" />
                            </svg>
                        </div>

                        <p class="text-sm font-medium text-gray-700">
                            <span class="text-amber-600 underline underline-offset-2 decoration-amber-300">Dateien auswählen</span>
                            oder hierher ziehen
                        </p>
                        <p class="mt-1 text-xs text-gray-400">.pro Dateien oder .zip Archive mit .pro Dateien</p>
                    </div>

                    <!-- Upload error toast -->
                    <Transition
                        enter-active-class="transition duration-300 ease-out"
                        enter-from-class="translate-y-2 opacity-0"
                        enter-to-class="translate-y-0 opacity-100"
                        leave-active-class="transition duration-200 ease-in"
                        leave-from-class="opacity-100"
                        leave-to-class="opacity-0"
                    >
                        <div
                            v-if="uploadError"
                            class="absolute inset-x-0 bottom-0 bg-orange-50 border-t border-orange-200 px-4 py-2.5 text-center text-sm font-medium text-orange-700"
                        >
                            {{ uploadError }}
                        </div>
                    </Transition>
                </div>

                <!-- Upload Success Toast -->
                <Transition
                    enter-active-class="transition duration-300 ease-out"
                    enter-from-class="translate-y-2 opacity-0"
                    enter-to-class="translate-y-0 opacity-100"
                    leave-active-class="transition duration-200 ease-in"
                    leave-from-class="opacity-100"
                    leave-to-class="opacity-0"
                >
                    <div
                        v-if="uploadSuccess"
                        class="mb-4 rounded-lg border border-emerald-300 bg-emerald-50 px-4 py-3 text-sm font-medium text-emerald-700"
                    >
                        {{ uploadSuccess }}
                    </div>
                </Transition>

                <!-- Search Bar -->
                <div class="relative mb-6">
                    <div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-4">
                        <svg class="h-4.5 w-4.5 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                            <path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
                        </svg>
                    </div>
                    <input
                        data-testid="song-list-search-input"
                        v-model="search"
                        type="text"
                        placeholder="Songs durchsuchen (Name oder CCLI-ID)…"
                        class="w-full rounded-xl border border-gray-200 bg-white py-3 pl-11 pr-4 text-sm text-gray-900 shadow-sm transition-all placeholder:text-gray-400 focus:border-amber-300 focus:outline-none focus:ring-2 focus:ring-amber-400/30"
                    />
                    <Transition
                        enter-active-class="transition duration-150"
                        enter-from-class="opacity-0"
                        enter-to-class="opacity-100"
                        leave-active-class="transition duration-100"
                        leave-from-class="opacity-100"
                        leave-to-class="opacity-0"
                    >
                        <button
                            data-testid="song-list-search-clear"
                            v-if="search"
                            @click="search = ''"
                            class="absolute inset-y-0 right-0 flex items-center pr-4 text-gray-400 hover:text-gray-600"
                        >
                            <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
                            </svg>
                        </button>
                    </Transition>
                </div>

                <!-- CCLI Import Buttons -->
                <div class="mb-4 flex items-center gap-2">
                    <button
                        v-if="search"
                        type="button"
                        data-testid="songselect-search-button-songdb"
                        @click="openSongSelectSearch"
                        class="inline-flex items-center gap-1 rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm font-medium text-gray-700 shadow-sm transition hover:bg-gray-50"
                    >
                        Auf SongSelect suchen ↗
                    </button>
                    <button
                        type="button"
                        data-testid="open-ccli-paste-dialog-button-songdb"
                        @click="ccliDialogOpen = true"
                        class="inline-flex items-center gap-1 rounded-md border border-blue-300 bg-blue-50 px-3 py-1.5 text-sm font-medium text-blue-700 shadow-sm transition hover:bg-blue-100"
                    >
                        Aus CCLI importieren
                    </button>

                    <button
                        type="button"
                        data-testid="song-list-content-filter"
                        @click="onlyWithContent = !onlyWithContent"
                        class="ml-auto inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium shadow-sm transition"
                        :class="onlyWithContent
                            ? 'border-emerald-300 bg-emerald-50 text-emerald-700 hover:bg-emerald-100'
                            : 'border-gray-300 bg-white text-gray-600 hover:bg-gray-50'"
                        :title="onlyWithContent ? 'Zeige nur Songs mit Inhalt' : 'Zeige auch Songs ohne Inhalt'"
                    >
                        <svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                            <path stroke-linecap="round" stroke-linejoin="round" d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 01-.659 1.591l-5.432 5.432a2.25 2.25 0 00-.659 1.591v2.927a2.25 2.25 0 01-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 00-.659-1.591L3.659 7.409A2.25 2.25 0 013 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0112 3z" />
                        </svg>
                        {{ onlyWithContent ? 'Nur mit Inhalt' : 'Alle Songs' }}
                    </button>
                </div>

                <!-- Song Count + Loading -->
                <div class="mb-3 flex items-center justify-between px-1">
                    <p class="text-xs font-medium text-gray-500">
                        <template v-if="!loading">
                            {{ meta.total }} {{ meta.total === 1 ? 'Song' : 'Songs' }}
                            <span v-if="search" class="text-gray-400">für „{{ search }}"</span>
                        </template>
                        <template v-else>
                            <span class="inline-flex items-center gap-1.5">
                                <span class="inline-block h-3 w-3 animate-spin rounded-full border-2 border-amber-400 border-t-transparent"></span>
                                Lade Songs…
                            </span>
                        </template>
                    </p>
                </div>

                <!-- Table -->
                <div class="overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm">
                    <div v-if="!loading && songs.length === 0" class="p-12 text-center">
                        <div class="mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-2xl bg-gray-100">
                            <svg class="h-7 w-7 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M9 9l10.5-3m0 6.553v3.75a2.25 2.25 0 01-1.632 2.163l-1.32.377a1.803 1.803 0 11-.99-3.467l2.31-.66a2.25 2.25 0 001.632-2.163zm0 0V2.25L9 5.25v10.303m0 0v3.75a2.25 2.25 0 01-1.632 2.163l-1.32.377a1.803 1.803 0 01-.99-3.467l2.31-.66A2.25 2.25 0 009 15.553z" />
                            </svg>
                        </div>
                        <p class="text-sm font-medium text-gray-600">
                            {{ search ? 'Keine Songs gefunden' : 'Noch keine Songs vorhanden' }}
                        </p>
                        <p class="mt-1 text-xs text-gray-400">
                            {{ search ? 'Versuch einen anderen Suchbegriff.' : 'Lade .pro Dateien hoch, um Songs hinzuzufügen.' }}
                        </p>
                    </div>

                    <div v-else class="overflow-x-auto">
                        <table class="min-w-full divide-y divide-gray-200">
                            <thead class="bg-gray-50/80">
                                <tr>
                                    <th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-gray-500">Titel</th>
                                    <th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-gray-500">CCLI-ID</th>
                                    <th class="hidden px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-gray-500 md:table-cell">Erstellt</th>
                                    <th class="hidden px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-gray-500 lg:table-cell">Letzte Änderung</th>
                                    <th class="hidden px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-gray-500 lg:table-cell">Zuletzt verwendet</th>
                                    <th class="px-4 py-3 text-center text-xs font-semibold uppercase tracking-wider text-gray-500">Übersetzung</th>
                                    <th class="px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500">Aktionen</th>
                                </tr>
                            </thead>

                            <tbody class="divide-y divide-gray-100 bg-white">
                                <tr
                                    v-for="song in songs"
                                    :key="song.id"
                                    data-testid="song-list-row"
                                    class="group transition-colors"
                                    :class="song.has_content === false
                                        ? 'bg-orange-50 hover:bg-orange-100/60'
                                        : 'hover:bg-amber-50/30'"
                                >
                                    <!-- Titel -->
                                    <td class="px-4 py-3.5">
                                        <div class="font-medium text-gray-900">{{ song.title }}</div>
                                        <div v-if="song.author" class="mt-0.5 text-xs text-gray-400">{{ song.author }}</div>
                                        <div
                                            v-if="song.has_content === false"
                                            data-testid="song-list-no-content-note"
                                            class="mt-1 inline-flex items-center gap-1 rounded-full bg-orange-100 px-2 py-0.5 text-[11px] font-semibold text-orange-700"
                                        >
                                            <svg class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                                <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
                                            </svg>
                                            Ohne Inhalt
                                        </div>
                                    </td>

                                    <!-- CCLI-ID -->
                                    <td class="px-4 py-3.5">
                                        <span
                                            v-if="song.ccli_id"
                                            class="inline-flex items-center rounded-md bg-gray-100 px-2 py-0.5 text-xs font-mono font-medium text-gray-700"
                                        >
                                            {{ song.ccli_id }}
                                        </span>
                                        <span v-else class="text-xs text-gray-300">–</span>
                                    </td>

                                    <!-- Erstellt -->
                                    <td class="hidden px-4 py-3.5 text-sm text-gray-500 md:table-cell">
                                        {{ formatDate(song.created_at) }}
                                    </td>

                                    <!-- Letzte Änderung -->
                                    <td class="hidden px-4 py-3.5 text-sm text-gray-500 lg:table-cell">
                                        {{ formatDateTime(song.updated_at) }}
                                    </td>

                                    <!-- Zuletzt verwendet -->
                                    <td class="hidden px-4 py-3.5 text-sm lg:table-cell">
                                        <span v-if="song.last_used_in_service" class="text-gray-700">
                                            {{ formatDate(song.last_used_in_service) }}
                                        </span>
                                        <span v-else class="text-xs text-gray-300">noch nie</span>
                                    </td>

                                    <!-- Übersetzung -->
                                    <td class="px-4 py-3.5 text-center">
                                        <span
                                            v-if="song.has_translation"
                                            class="inline-flex items-center gap-1 rounded-full bg-emerald-50 px-2.5 py-0.5 text-xs font-semibold text-emerald-700"
                                            title="Übersetzung vorhanden"
                                        >
                                            <svg class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
                                                <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" />
                                            </svg>
                                            Ja
                                        </span>
                                        <span
                                            v-else
                                            class="inline-flex items-center rounded-full bg-gray-50 px-2.5 py-0.5 text-xs font-medium text-gray-400"
                                        >
                                            Nein
                                        </span>
                                    </td>

                                    <!-- Aktionen -->
                                    <td class="px-4 py-3.5">
                                        <div class="flex items-center justify-end gap-1.5 opacity-0 transition-opacity group-hover:opacity-100">
                                            <!-- Vorschau -->
                                            <button
                                                data-testid="song-list-preview-button"
                                                type="button"
                                                class="inline-flex items-center rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs font-medium text-gray-700 shadow-sm transition-all hover:border-indigo-300 hover:bg-indigo-50 hover:text-indigo-700"
                                                title="Vorschau"
                                                @click="openPreview(song)"
                                            >
                                                <svg class="mr-1 h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                                    <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z" />
                                                    <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
                                                </svg>
                                                Vorschau
                                            </button>

                                            <!-- Bearbeiten -->
                                            <button
                                                data-testid="song-list-edit-button"
                                                type="button"
                                                class="inline-flex items-center rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs font-medium text-gray-700 shadow-sm transition-all hover:border-amber-300 hover:bg-amber-50 hover:text-amber-700"
                                                title="Bearbeiten"
                                                @click="openEditModal(song)"
                                            >
                                                <svg class="mr-1 h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                                    <path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" />
                                                </svg>
                                                Bearbeiten
                                            </button>

                                            <!-- Übersetzen -->
                                            <a
                                                v-if="!song.has_translation"
                                                data-testid="song-list-translate-link"
                                                :href="`/songs/${song.id}/translate`"
                                                class="inline-flex items-center rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs font-medium text-gray-700 shadow-sm transition-all hover:border-sky-300 hover:bg-sky-50 hover:text-sky-700"
                                                title="Übersetzen"
                                            >
                                                <svg class="mr-1 h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                                    <path stroke-linecap="round" stroke-linejoin="round" d="M10.5 21l5.25-11.25L21 21m-9-3h7.5M3 5.621a48.474 48.474 0 016-.371m0 0c1.12 0 2.233.038 3.334.114M9 5.25V3m3.334 2.364C11.176 10.658 7.69 15.08 3 17.502m9.334-12.138c.896.061 1.785.147 2.666.257m-4.589 8.495a18.023 18.023 0 01-3.827-5.802" />
                                                </svg>
                                                Übersetzen
                                            </a>

                                            <!-- Herunterladen -->
                                            <a
                                                data-testid="song-list-download-button"
                                                :href="`/api/songs/${song.id}/download-pro`"
                                                class="inline-flex items-center rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs font-medium text-gray-700 shadow-sm transition-all hover:border-emerald-300 hover:bg-emerald-50 hover:text-emerald-700"
                                                title="Als .pro herunterladen"
                                            >
                                                <svg class="mr-1 h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                                    <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" />
                                                </svg>
                                                Herunterladen
                                            </a>

                                            <!-- Löschen -->
                                            <button
                                                data-testid="song-list-delete-button"
                                                type="button"
                                                class="inline-flex items-center rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs font-medium text-gray-700 shadow-sm transition-all hover:border-red-300 hover:bg-red-50 hover:text-red-700"
                                                title="Löschen"
                                                :disabled="deleting === song.id"
                                                @click.stop="confirmDelete(song)"
                                            >
                                                <svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                                    <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                                </svg>
                                            </button>
                                        </div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>

                <!-- Pagination -->
                <div
                    v-if="meta.last_page > 1"
                    class="mt-4 flex items-center justify-between px-1"
                >
                    <p class="text-xs text-gray-500">
                        Seite {{ meta.current_page }} von {{ meta.last_page }}
                    </p>

                    <nav class="flex items-center gap-1">
                        <button
                            data-testid="song-list-pagination-prev"
                            :disabled="meta.current_page <= 1"
                            class="inline-flex h-8 w-8 items-center justify-center rounded-lg border border-gray-200 bg-white text-xs text-gray-600 shadow-sm transition-all hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40"
                            @click="goToPage(meta.current_page - 1)"
                        >
                            <svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
                            </svg>
                        </button>

                        <template v-for="page in pageRange()" :key="page">
                            <span
                                v-if="page === '...'"
                                class="flex h-8 w-8 items-center justify-center text-xs text-gray-400"
                            >…</span>
                            <button
                                v-else
                                class="inline-flex h-8 w-8 items-center justify-center rounded-lg border text-xs font-medium shadow-sm transition-all"
                                :class="page === meta.current_page
                                    ? 'border-amber-300 bg-amber-50 text-amber-700'
                                    : 'border-gray-200 bg-white text-gray-600 hover:bg-gray-50'"
                                @click="goToPage(page)"
                            >
                                {{ page }}
                            </button>
                        </template>

                        <button
                            data-testid="song-list-pagination-next"
                            :disabled="meta.current_page >= meta.last_page"
                            class="inline-flex h-8 w-8 items-center justify-center rounded-lg border border-gray-200 bg-white text-xs text-gray-600 shadow-sm transition-all hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40"
                            @click="goToPage(meta.current_page + 1)"
                        >
                            <svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
                            </svg>
                        </button>
                    </nav>
                </div>

                <!-- Delete Confirm Modal -->
                <Teleport to="body">
                    <Transition
                        enter-active-class="transition duration-200 ease-out"
                        enter-from-class="opacity-0"
                        enter-to-class="opacity-100"
                        leave-active-class="transition duration-150 ease-in"
                        leave-from-class="opacity-100"
                        leave-to-class="opacity-0"
                    >
                        <div
                            v-if="showDeleteConfirm"
                            class="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm"
                            @click.self="cancelDelete"
                        >
                            <Transition
                                enter-active-class="transition duration-200 ease-out"
                                enter-from-class="scale-95 opacity-0"
                                enter-to-class="scale-100 opacity-100"
                                leave-active-class="transition duration-150 ease-in"
                                leave-from-class="scale-100 opacity-100"
                                leave-to-class="scale-95 opacity-0"
                            >
                                <div
                                    v-if="showDeleteConfirm"
                                    class="w-full max-w-sm rounded-2xl bg-white p-6 shadow-2xl"
                                >
                                    <div class="mb-4 flex h-11 w-11 items-center justify-center rounded-xl bg-red-50">
                                        <svg class="h-5.5 w-5.5 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
                                        </svg>
                                    </div>

                                    <h3 class="text-base font-semibold text-gray-900">Song löschen?</h3>
                                    <p class="mt-1.5 text-sm text-gray-500">
                                        „{{ deleteTarget?.title }}" wird gelöscht. Diese Aktion kann rückgängig gemacht werden.
                                    </p>

                                    <div class="mt-5 flex items-center justify-end gap-2.5">
                                        <button
                                            data-testid="song-list-delete-cancel-button"
                                            type="button"
                                            class="rounded-lg border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm transition hover:bg-gray-50"
                                            @click="cancelDelete"
                                        >
                                            Abbrechen
                                        </button>
                                        <button
                                            data-testid="song-list-delete-confirm-button"
                                            type="button"
                                            class="inline-flex items-center gap-1.5 rounded-lg border border-red-300 bg-red-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition hover:bg-red-700 disabled:opacity-60"
                                            :disabled="deleting"
                                            @click="deleteSong"
                                        >
                                            <span v-if="deleting" class="inline-block h-3.5 w-3.5 animate-spin rounded-full border-2 border-white border-t-transparent"></span>
                                            Löschen
                                        </button>
                                    </div>
                                </div>
                            </Transition>
                        </div>
                    </Transition>
                </Teleport>
            </div>
        </div>

        <!-- Song Edit Modal -->
        <SongEditModal
            data-testid="song-list-edit-modal"
            :show="showEditModal"
            :song-id="editSongId"
            @close="closeEditModal"
            @updated="onSongUpdated"
        />

        <!-- Song Preview Modal -->
        <Teleport to="body">
            <Transition
                enter-active-class="transition duration-200 ease-out"
                enter-from-class="opacity-0"
                enter-to-class="opacity-100"
                leave-active-class="transition duration-150 ease-in"
                leave-from-class="opacity-100"
                leave-to-class="opacity-0"
            >
                <div
                    v-if="previewSong"
                    class="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm"
                    @click.self="closePreview"
                >
                    <div class="w-full max-w-2xl max-h-[80vh] overflow-auto rounded-2xl bg-white p-6 shadow-2xl">
                        <div class="flex items-center justify-between mb-4">
                            <h3 class="text-lg font-semibold text-gray-900">
                                {{ previewSong?.title || 'Vorschau' }}
                            </h3>
                            <button type="button" class="text-gray-400 hover:text-gray-600" @click="closePreview">
                                <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                    <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
                                </svg>
                            </button>
                        </div>

                        <div v-if="previewLoading" class="flex items-center justify-center py-12">
                            <span class="inline-block h-6 w-6 animate-spin rounded-full border-2 border-amber-400 border-t-transparent"></span>
                        </div>

                        <div v-else-if="previewData" class="space-y-4">
                            <div v-for="(group, idx) in previewData.groups" :key="idx" class="rounded-lg border border-gray-200 p-4">
                                <div class="mb-2 flex items-center gap-2">
                                    <span
                                        class="inline-flex rounded-full px-3 py-1 text-xs font-semibold text-white"
                                        :style="{ backgroundColor: group.color || '#6b7280' }"
                                    >
                                        {{ group.name }}
                                    </span>
                                </div>
                                <div v-for="(slide, sIdx) in group.slides" :key="sIdx" class="mt-2 whitespace-pre-wrap text-sm text-gray-700 leading-relaxed">{{ slide.text_content }}</div>
                            </div>

                            <div v-if="previewData.song?.copyright_text" class="border-t pt-3 text-xs text-gray-400">
                                {{ previewData.song.copyright_text }}
                            </div>
                        </div>

                        <div v-else class="py-8 text-center text-sm text-gray-500">
                            Kein Arrangement vorhanden.
                        </div>
                    </div>
                </div>
            </Transition>
        </Teleport>

    </AuthenticatedLayout>

    <!-- CCLI Paste Dialog -->
    <CcliPasteDialog
        :open="ccliDialogOpen"
        mode="songdb"
        @close="ccliDialogOpen = false"
        @imported="(songId, mode) => { ccliDialogOpen = false; if (mode === 'stay') { router.reload({ only: ['songs'] }) } }"
        @edit-song="(id) => { ccliDialogOpen = false; openEditModal({ id }) }"
    />
</template>
