<script setup>
import { computed, ref, watch } from 'vue'
import { Link, router } from '@inertiajs/vue3'

const props = defineProps({
    agendaItem: { type: Object, required: true },
    songsCatalog: { type: Array, default: () => [] },
    serviceId: { type: Number, required: true },
})

const emit = defineEmits(['arrangement-selected', 'slides-updated'])

const serviceSong = computed(() => props.agendaItem.serviceSong ?? props.agendaItem.service_song ?? null)

const isMatched = computed(() => serviceSong.value?.song_id != null)

// Matched song id for linking to the SongDB edit modal (Songs/Index reads #song-<id>).
const matchedSongId = computed(() => serviceSong.value?.song?.id ?? serviceSong.value?.song_id ?? null)

const songDetailHref = computed(() =>
    matchedSongId.value != null ? `${route('songs.index')}#song-${matchedSongId.value}` : null,
)

// Matched song whose default arrangement has NO content slide -> not verified.
const missingContentSlides = computed(
    () => isMatched.value && serviceSong.value?.has_content_slides === false,
)

const useTranslation = ref(false)
const downloading = ref(false)
const toastMessage = ref('')
const toastVariant = ref('info')

function showToast(message, variant = 'info') {
    toastMessage.value = message
    toastVariant.value = variant
    setTimeout(() => {
        toastMessage.value = ''
    }, 2500)
}

function toastClasses() {
    if (toastVariant.value === 'success') return 'border-emerald-300 bg-emerald-50 text-emerald-700'
    if (toastVariant.value === 'warning') return 'border-amber-300 bg-amber-50 text-amber-700'
    if (toastVariant.value === 'error') return 'border-red-300 bg-red-50 text-red-700'
    return 'border-slate-300 bg-slate-50 text-slate-700'
}

watch(
    () => serviceSong.value,
    (ss) => {
        if (ss) {
            useTranslation.value = ss.use_translation ?? false
        }
    },
    { immediate: true, deep: true },
)

const responsibleNames = computed(() => {
    const r = props.agendaItem.responsible
    if (!r) return ''
    // CTS returns {text: "...", persons: [{person: {title: "Name"}, service: "[Role]"}]}
    if (r.persons && Array.isArray(r.persons)) {
        const names = r.persons
            .map((p) => p.person?.title || p.name || '')
            .filter(Boolean)
        if (names.length > 0) return [...new Set(names)].join(', ')
    }
    // Fallback: use text field
    if (r.text) return r.text
    // Legacy: array of objects
    if (Array.isArray(r)) {
        return r.map((p) => p.person?.title || p.name || p.title || p.personName || '').filter(Boolean).join(', ')
    }
    return ''
})

const formattedStart = computed(() => {
    const s = props.agendaItem.start
    if (!s) return ''
    const d = new Date(s)
    if (isNaN(d.getTime())) return s
    return d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', timeZone: 'Europe/Berlin' })
})

const formattedDuration = computed(() => {
    const dur = props.agendaItem.duration
    if (!dur || dur === '0') return ''
    const totalSeconds = parseInt(dur, 10)
    if (isNaN(totalSeconds) || totalSeconds <= 0) return dur
    const hours = Math.floor(totalSeconds / 3600)
    const minutes = Math.floor((totalSeconds % 3600) / 60)
    return hours > 0 ? `${hours}:${String(minutes).padStart(2, '0')}` : `0:${String(minutes).padStart(2, '0')}`
})

const rowBgClass = computed(() => {
    if (!isMatched.value) return 'bg-amber-50'
    if (serviceSong.value?.song_arrangement_id) return 'bg-emerald-50'
    return 'bg-yellow-50'
})

const borderClass = computed(() => {
    if (!isMatched.value) return 'border-l-4 border-l-amber-400'
    if (serviceSong.value?.song_arrangement_id) return 'border-l-4 border-l-emerald-500'
    return 'border-l-4 border-l-yellow-400'
})

async function requestCreation() {
    try {
        await window.axios.post(`/api/service-songs/${serviceSong.value.id}/request`)
        showToast('Anfrage wurde gesendet.', 'success')
        router.reload({ preserveScroll: true, preserveState: true })
    } catch {
        showToast('Anfrage konnte nicht gesendet werden.', 'error')
    }
}

async function updateUseTranslation() {
    try {
        await window.axios.patch(`/api/service-songs/${serviceSong.value.id}`, {
            use_translation: Boolean(useTranslation.value),
        })
        showToast('Übersetzung wurde gespeichert.', 'success')
    } catch {
        showToast('Speichern fehlgeschlagen.', 'error')
    }
}

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

async function downloadBundle() {
    downloading.value = true
    try {
        const response = await fetch(
            route('services.agenda-item.download', {
                service: props.serviceId,
                agendaItem: props.agendaItem.id,
            }),
            {
                headers: {
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content ?? '',
                },
            },
        )

        if (!response.ok) {
            const data = await response.json().catch(() => ({}))
            showToast(data.message || 'Fehler beim Herunterladen.', 'error')
            return
        }

        const disposition = response.headers.get('content-disposition')
        const filenameMatch = disposition?.match(/filename="?([^"]+)"?/)
        const filename = filenameMatch?.[1] || 'song.probundle'

        const blob = await response.blob()
        const url = URL.createObjectURL(blob)
        const a = document.createElement('a')
        a.href = url
        a.download = filename
        a.click()
        URL.revokeObjectURL(url)

        showToast('Download gestartet.', 'success')
    } catch {
        showToast('Fehler beim Herunterladen.', 'error')
    } finally {
        downloading.value = false
    }
}
</script>

<template>
    <!-- Toast row -->
    <tr v-if="toastMessage">
        <td colspan="6" class="px-3 py-2">
            <div
                class="rounded-lg border px-4 py-2 text-sm font-medium"
                :class="toastClasses()"
                role="status"
            >
                {{ toastMessage }}
            </div>
        </td>
    </tr>

    <!-- Main song row -->
    <tr
        class="border-b border-gray-100"
        :class="rowBgClass"
        data-testid="song-agenda-item"
    >
        <!-- Nr -->
        <td class="py-2.5 pr-3 align-top" :class="borderClass">
            <span class="text-xs text-gray-400 tabular-nums">{{ agendaItem.position || agendaItem.sort_order }}</span>
        </td>

        <!-- Zeit -->
        <td class="py-2.5 pr-3 align-top">
            <span v-if="formattedStart" class="text-xs text-gray-500 tabular-nums">{{ formattedStart }}</span>
        </td>

        <!-- Dauer -->
        <td class="py-2.5 pr-3 align-top">
            <span v-if="formattedDuration" class="text-xs text-gray-500 tabular-nums">{{ formattedDuration }}</span>
        </td>

        <!-- Titel -->
        <td class="py-2.5 pr-3 align-top">
            <div class="flex items-center gap-2 flex-wrap">
                <!-- Song title -->
                <Link
                    v-if="isMatched && songDetailHref"
                    :href="songDetailHref"
                    class="font-medium text-gray-900 underline decoration-gray-300 decoration-dotted underline-offset-2 transition hover:text-emerald-700 hover:decoration-emerald-400"
                    data-testid="song-agenda-title"
                    title="Song in der Song-Datenbank öffnen"
                >
                    {{ serviceSong?.cts_song_name || agendaItem.title || '-' }}
                </Link>
                <span v-else class="font-medium text-gray-900" data-testid="song-agenda-title">
                    {{ serviceSong?.cts_song_name || agendaItem.title || '-' }}
                </span>

                <!-- No content slides warning (matched but default arrangement empty) -->
                <span
                    v-if="missingContentSlides"
                    class="inline-flex items-center gap-1 rounded-full bg-red-100 px-2 py-0.5 text-[11px] font-semibold text-red-700"
                    data-testid="song-no-content"
                    title="Standard-Arrangement enthält keine Inhaltsfolien"
                >
                    <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>
                    Keine Inhaltsfolien
                </span>

                <!-- CCLI pill -->
                <span class="rounded-full bg-gray-100 px-2 py-0.5 text-[11px] font-medium text-gray-500">
                    CCLI: {{ serviceSong?.song?.ccli_id || serviceSong?.cts_ccli_id || '-' }}
                </span>

                <!-- Note -->
                <p v-if="agendaItem.note" class="mt-0.5 basis-full text-xs text-gray-400">
                    {{ agendaItem.note }}
                </p>
            </div>
        </td>

        <!-- Verantwortlich -->
        <td class="py-2.5 pr-3 align-top">
            <span v-if="responsibleNames" class="text-xs text-gray-500">{{ responsibleNames }}</span>
        </td>

        <!-- Aktionen -->
        <td class="py-2.5 align-top">
            <div class="flex items-center justify-end gap-1">
                <!-- Assign status -->
                <span
                    v-if="missingContentSlides"
                    class="inline-flex h-2 w-2 rounded-full bg-red-500"
                    title="Keine Inhaltsfolien"
                ></span>
                <span
                    v-else-if="isMatched"
                    class="inline-flex h-2 w-2 rounded-full bg-emerald-500"
                    title="Zugeordnet"
                ></span>
                <span
                    v-else
                    class="inline-flex h-2 w-2 rounded-full bg-amber-400"
                    title="Nicht zugeordnet"
                ></span>

                <!-- Translation flag -->
                <span
                    v-if="serviceSong?.song?.has_translation"
                    class="text-sm leading-none"
                    title="Mit Übersetzung"
                >🇩🇪🇬🇧</span>
                <span
                    v-else
                    class="text-sm leading-none"
                    title="Nur Deutsch"
                >🇩🇪</span>

                <!-- Translation checkbox (only when matched + has translation) -->
                <label
                    v-if="isMatched && serviceSong?.song?.has_translation"
                    class="inline-flex items-center"
                    title="Übersetzung verwenden"
                >
                    <input
                        v-model="useTranslation"
                        type="checkbox"
                        class="h-3.5 w-3.5 rounded border-gray-300 text-emerald-600 focus:ring-emerald-500"
                        data-testid="song-translation-checkbox"
                        @change="updateUseTranslation"
                    />
                </label>

                <!-- Download bundle -->
                <button
                    v-if="isMatched"
                    type="button"
                    class="flex h-7 w-7 items-center justify-center rounded text-gray-400 transition hover:bg-emerald-100 hover:text-emerald-600 disabled:opacity-50"
                    data-testid="song-download-bundle"
                    title="Als .probundle herunterladen"
                    :disabled="downloading"
                    @click="downloadBundle"
                >
                    <svg v-if="downloading" class="h-4 w-4 animate-spin" fill="none" viewBox="0 0 24 24">
                        <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                        <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
                    </svg>
                    <svg v-else 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="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>
                </button>

                <!-- Edit / assign song — opens dialog for both matched and unmatched -->
                <button
                    type="button"
                    class="flex h-7 w-7 items-center justify-center rounded text-gray-400 transition hover:bg-gray-100 hover:text-gray-600"
                    data-testid="song-edit-arrangement"
                    :title="isMatched ? 'Arrangement bearbeiten' : 'Song zuordnen'"
                    @click="emit('arrangement-selected', serviceSong)"
                >
                    <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="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 010 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 010-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28z" />
                        <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
                    </svg>
                </button>

                <!-- Request creation button (only when not matched) -->
                <button
                    v-if="!isMatched && serviceSong"
                    type="button"
                    class="flex h-7 w-7 items-center justify-center rounded text-amber-500 transition hover:bg-amber-50 hover:text-amber-700"
                    data-testid="song-request-creation"
                    :title="serviceSong.request_sent_at ? 'Anfrage gesendet am ' + formatDateTime(serviceSong.request_sent_at) : 'Erstellung anfragen'"
                    @click="requestCreation"
                >
                    <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="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
                    </svg>
                </button>
            </div>
        </td>
    </tr>
</template>
