<script setup>
import { computed, ref, watch, onMounted, onUnmounted } from 'vue'
import { router } from '@inertiajs/vue3'
import axios from 'axios'
import { VueDraggable } from 'vue-draggable-plus'
import SlideUploader from '@/Components/SlideUploader.vue'
import ConfirmDialog from '@/Components/ConfirmDialog.vue'

const props = defineProps({
    agendaItem: { type: Object, required: true },
    serviceId: { type: Number, required: true },
    serviceDate: { type: String, default: null },
})

const emit = defineEmits(['slides-updated', 'scroll-to-info'])

const showUploader = ref(false)
const downloading = ref(false)

// Uploader outside-click handling
const toggleBtnRef = ref(null)
const uploaderRowRef = ref(null)

function onDocumentClick(event) {
    if (!showUploader.value) return
    const target = event.target
    if (toggleBtnRef.value?.contains(target)) return
    if (uploaderRowRef.value?.contains(target)) return
    showUploader.value = false
}

onMounted(() => document.addEventListener('click', onDocumentClick))
onUnmounted(() => document.removeEventListener('click', onDocumentClick))

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(() => ({}))
            alert(data.message || 'Fehler beim Herunterladen.')
            return
        }

        const disposition = response.headers.get('content-disposition')
        const filenameMatch = disposition?.match(/filename="?([^"]+)"?/)
        const filename = filenameMatch?.[1] || 'element.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)
    } catch {
        alert('Fehler beim Herunterladen.')
    } finally {
        downloading.value = false
    }
}

// Preview state
const previewSlide = ref(null)
const previewIndex = ref(-1)

// Delete confirmation state
const confirmingDelete = ref(false)
const slideToDelete = ref(null)
const deleting = ref(false)

// Hover preview state
const hoverSlide = ref(null)
const hoverPosition = ref({ x: 0, y: 0 })

const allSlides = computed(() => props.agendaItem.slides ?? [])

// Draggable local slides (sorted by sort_order)
const localSlides = ref([])

watch(() => props.agendaItem.slides, (newSlides) => {
    localSlides.value = [...(newSlides ?? [])].sort((a, b) => {
        const orderA = a.sort_order ?? 0
        const orderB = b.sort_order ?? 0
        if (orderA !== orderB) return orderA - orderB
        return new Date(a.uploaded_at) - new Date(b.uploaded_at)
    })
}, { immediate: true, deep: true })

function onDragEnd() {
    const reordered = localSlides.value.map((slide, index) => ({
        id: slide.id,
        sort_order: index + 1,
    }))

    axios.post(route('slides.reorder'), { slides: reordered })
        .then(() => emit('slides-updated'))
        .catch(console.error)
}

const responsibleNames = computed(() => {
    const r = props.agendaItem.responsible
    if (!r) return ''
    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(', ')
    }
    if (r.text) return r.text
    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 (props.agendaItem.is_announcement_position) return 'bg-blue-50'
    if (props.agendaItem.is_sermon) return 'bg-purple-50'
    if (props.agendaItem.slides?.length > 0) return 'bg-emerald-50'
    return ''
})

const borderClass = computed(() => {
    if (props.agendaItem.is_announcement_position) return 'border-l-4 border-l-blue-400'
    if (props.agendaItem.is_sermon) return 'border-l-4 border-l-purple-400'
    if (props.agendaItem.slides?.length > 0) return 'border-l-4 border-l-emerald-500'
    return ''
})

function thumbnailUrl(slide) {
    if (!slide.thumbnail_filename) return null
    return `/storage/${slide.thumbnail_filename}`
}

function fullImageUrl(slide) {
    if (!slide.stored_filename) return null
    return `/storage/${slide.stored_filename}`
}

function onUploaded() {
    showUploader.value = false
    emit('slides-updated')
}

// Preview with navigation
function openPreview(slide) {
    previewSlide.value = slide
    previewIndex.value = allSlides.value.findIndex((s) => s.id === slide.id)
}

function closePreview() {
    previewSlide.value = null
    previewIndex.value = -1
}

function prevPreview() {
    if (previewIndex.value <= 0) return
    previewIndex.value--
    previewSlide.value = allSlides.value[previewIndex.value]
}

function nextPreview() {
    if (previewIndex.value >= allSlides.value.length - 1) return
    previewIndex.value++
    previewSlide.value = allSlides.value[previewIndex.value]
}

const hasPrev = computed(() => previewIndex.value > 0)
const hasNext = computed(() => previewIndex.value < allSlides.value.length - 1)

// Delete
function promptDelete(slide, event) {
    event.stopPropagation()
    slideToDelete.value = slide
    confirmingDelete.value = true
}

function cancelDelete() {
    confirmingDelete.value = false
    slideToDelete.value = null
}

function confirmDelete() {
    if (!slideToDelete.value) return
    deleting.value = true

    const deletedId = slideToDelete.value.id

    axios.delete(route('slides.destroy', deletedId))
        .then(() => {
            confirmingDelete.value = false
            slideToDelete.value = null
            deleting.value = false
            if (previewSlide.value?.id === deletedId) {
                previewSlide.value = null
                previewIndex.value = -1
            }
            emit('slides-updated')
            router.reload({ preserveScroll: true })
        })
        .catch(() => {
            deleting.value = false
        })
}

// Hover preview
function onThumbMouseEnter(slide, event) {
    const rect = event.target.getBoundingClientRect()
    hoverPosition.value = {
        x: rect.left + rect.width / 2,
        y: rect.top,
    }
    hoverSlide.value = slide
}

function onThumbMouseLeave() {
    hoverSlide.value = null
}

// Scroll to info block
function scrollToInfo() {
    emit('scroll-to-info')
}
</script>

<template>
    <!-- Main row -->
    <tr
        class="border-b border-gray-100"
        :class="rowBgClass || 'hover:bg-gray-50'"
        data-testid="agenda-item-row"
    >
        <!-- 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">
            <span class="font-medium text-gray-900" data-testid="agenda-item-title">{{ agendaItem.title }}</span>

            <!-- Badges inline -->
            <span
                v-if="agendaItem.is_announcement_position"
                class="ml-2 inline-flex items-center rounded-full bg-blue-100 px-2 py-0.5 text-[11px] font-medium text-blue-700"
            >
                Ankündigungen
            </span>
            <span
                v-if="agendaItem.is_sermon"
                class="ml-2 inline-flex items-center rounded-full bg-purple-100 px-2 py-0.5 text-[11px] font-medium text-purple-700"
            >
                Predigt
            </span>

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

            <!-- Slide thumbnails (all, wrap + drag-reorder + number badges) -->
            <VueDraggable
                v-if="localSlides.length"
                v-model="localSlides"
                class="mt-1 flex flex-wrap gap-1"
                @end="onDragEnd"
                item-key="id"
            >
                <div
                    v-for="(slide, index) in localSlides"
                    :key="slide.id"
                    class="group/thumb relative cursor-grab active:cursor-grabbing"
                >
                    <img
                        :src="thumbnailUrl(slide)"
                        class="h-8 w-14 cursor-pointer rounded border border-gray-200 object-cover transition-all hover:border-amber-400 hover:ring-1 hover:ring-amber-400/40"
                        :alt="slide.original_filename"
                        data-testid="agenda-slide-thumbnail"
                        @click="openPreview(slide)"
                        @mouseenter="onThumbMouseEnter(slide, $event)"
                        @mouseleave="onThumbMouseLeave"
                    />
                    <!-- Number badge -->
                    <span
                        class="pointer-events-none absolute -left-1 -top-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-white/90 px-1 text-[9px] font-semibold leading-none text-gray-700 shadow-sm ring-1 ring-gray-200 tabular-nums"
                    >
                        {{ index + 1 }}.
                    </span>
                    <!-- Delete X button -->
                    <button
                        data-testid="agenda-slide-delete-btn"
                        class="absolute -right-1 -top-1 hidden h-4 w-4 items-center justify-center rounded-full bg-red-500 text-white shadow-sm transition hover:bg-red-600 group-hover/thumb:flex"
                        title="Folie entfernen"
                        @click="promptDelete(slide, $event)"
                    >
                        <svg class="h-2.5 w-2.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3">
                            <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
                        </svg>
                    </button>
                </div>
            </VueDraggable>
        </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">
                <!-- Download bundle -->
                <button
                    v-if="agendaItem.slides?.length"
                    type="button"
                    class="flex h-7 w-7 flex-shrink-0 items-center justify-center rounded text-gray-400 transition-colors hover:bg-emerald-100 hover:text-emerald-600 disabled:opacity-50"
                    data-testid="agenda-item-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>

                <!-- Announcement row: scroll to info block instead of + button -->
                <button
                    v-if="agendaItem.is_announcement_position"
                    class="flex h-7 w-7 flex-shrink-0 items-center justify-center rounded text-blue-400 transition-colors hover:bg-blue-100 hover:text-blue-600"
                    data-testid="agenda-item-scroll-to-info"
                    title="Zu Info-Folien springen"
                    @click="scrollToInfo"
                >
                    <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="M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3" />
                    </svg>
                </button>

                <!-- Normal rows: + / x toggle for uploader -->
                <button
                    v-else
                    ref="toggleBtnRef"
                    class="flex h-7 w-7 flex-shrink-0 items-center justify-center rounded text-gray-400 transition-colors hover:bg-gray-100 hover:text-blue-500"
                    data-testid="agenda-item-add-slides"
                    :title="showUploader ? 'Schließen' : 'Folien hinzufügen'"
                    @click="showUploader = !showUploader"
                >
                    <svg v-if="!showUploader" 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="M12 4.5v15m7.5-7.5h-15" />
                    </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="M6 18L18 6M6 6l12 12" />
                    </svg>
                </button>
            </div>
        </td>
    </tr>

    <!-- Uploader row (spanning all columns) — not for announcement rows -->
    <tr v-if="showUploader && !agendaItem.is_announcement_position" ref="uploaderRowRef">
        <td colspan="6" class="border-b border-gray-100 px-3 pb-3">
            <SlideUploader
                type="agenda_item"
                :service-id="serviceId"
                :agenda-item-id="agendaItem.id"
                :show-expire-date="false"
                :inline="true"
                @uploaded="onUploaded"
            />
        </td>
    </tr>

    <!-- Hover preview tooltip (doubled size: w-[512px]) -->
    <Teleport to="body">
        <Transition
            enter-active-class="transition duration-150 ease-out"
            enter-from-class="opacity-0 scale-95"
            enter-to-class="opacity-100 scale-100"
            leave-active-class="transition duration-100 ease-in"
            leave-from-class="opacity-100 scale-100"
            leave-to-class="opacity-0 scale-95"
        >
            <div
                v-if="hoverSlide"
                class="pointer-events-none fixed z-50 -translate-x-1/2 -translate-y-full"
                :style="{ left: hoverPosition.x + 'px', top: (hoverPosition.y - 8) + 'px' }"
            >
                <div class="overflow-hidden rounded-lg border border-gray-200 bg-white shadow-xl">
                    <img
                        :src="thumbnailUrl(hoverSlide)"
                        :alt="hoverSlide.original_filename"
                        class="h-auto w-[512px] object-contain"
                    />
                </div>
            </div>
        </Transition>
    </Teleport>

    <!-- Full preview overlay with prev/next navigation -->
    <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="previewSlide"
                data-testid="agenda-slide-preview"
                class="fixed inset-0 z-[60] flex items-center justify-center bg-black/70 backdrop-blur-sm"
                @click.self="closePreview"
            >
                <!-- Image + controls -->
                <div class="relative max-h-[90vh] max-w-[90vw]">
                    <img
                        :src="fullImageUrl(previewSlide)"
                        :alt="previewSlide.original_filename"
                        class="max-h-[85vh] max-w-[85vw] rounded-lg object-contain shadow-2xl"
                    />

                    <!-- Previous arrow (left edge of image) -->
                    <button
                        v-if="hasPrev"
                        data-testid="agenda-slide-preview-prev"
                        class="absolute left-2 top-1/2 flex h-10 w-10 -translate-y-1/2 items-center justify-center rounded-full bg-black/50 text-white shadow-lg transition hover:bg-black/70"
                        title="Vorherige Folie"
                        @click="prevPreview"
                    >
                        <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="M15.75 19.5L8.25 12l7.5-7.5" />
                        </svg>
                    </button>

                    <!-- Next arrow (right edge of image) -->
                    <button
                        v-if="hasNext"
                        data-testid="agenda-slide-preview-next"
                        class="absolute right-2 top-1/2 flex h-10 w-10 -translate-y-1/2 items-center justify-center rounded-full bg-black/50 text-white shadow-lg transition hover:bg-black/70"
                        title="Nächste Folie"
                        @click="nextPreview"
                    >
                        <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="M8.25 4.5l7.5 7.5-7.5 7.5" />
                        </svg>
                    </button>

                    <!-- Slide counter -->
                    <div
                        v-if="allSlides.length > 1"
                        class="absolute bottom-4 left-1/2 -translate-x-1/2 rounded-full bg-black/60 px-3 py-1 text-xs font-medium text-white tabular-nums"
                    >
                        {{ previewIndex + 1 }} / {{ allSlides.length }}
                    </div>

                    <div class="absolute -top-3 -right-3 flex gap-2">
                        <!-- Download button -->
                        <a
                            :href="fullImageUrl(previewSlide)"
                            :download="previewSlide.original_filename"
                            class="flex h-10 w-10 items-center justify-center rounded-full bg-emerald-600 text-white shadow-lg transition hover:bg-emerald-700"
                            title="Herunterladen"
                            data-testid="agenda-slide-preview-download"
                        >
                            <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="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>
                        </a>
                        <!-- Close button -->
                        <button
                            @click="closePreview"
                            class="flex h-10 w-10 items-center justify-center rounded-full bg-gray-800 text-white shadow-lg transition hover:bg-gray-700"
                            title="Schließen"
                            data-testid="agenda-slide-preview-close"
                        >
                            <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>
            </div>
        </Transition>
    </Teleport>

    <!-- Delete confirmation dialog -->
    <ConfirmDialog
        :show="confirmingDelete"
        title="Folie löschen?"
        :message="`Möchtest du die Folie '${slideToDelete?.original_filename || ''}' wirklich löschen?`"
        confirm-label="Löschen"
        cancel-label="Abbrechen"
        variant="danger"
        @confirm="confirmDelete"
        @cancel="cancelDelete"
    />
</template>
