<script setup>
import { ref, computed } from 'vue'
import { router } from '@inertiajs/vue3'
import Vue3Dropzone from '@jaxtheprime/vue3-dropzone'
import '@jaxtheprime/vue3-dropzone/dist/style.css'

const props = defineProps({
    type: {
        type: String,
        required: true,
        validator: (v) => ['information', 'moderation', 'sermon'].includes(v),
    },
    serviceId: {
        type: [Number, null],
        default: null,
    },
    showExpireDate: {
        type: Boolean,
        default: false,
    },
})

const emit = defineEmits(['uploaded'])

const files = ref([])
const expireDate = ref('')
const uploading = ref(false)
const uploadProgress = ref(0)
const uploadError = ref('')
const uploadedCount = ref(0)
const totalCount = ref(0)

const acceptedTypes = [
    'image/png',
    'image/jpg',
    'image/jpeg',
    'application/vnd.ms-powerpoint',
    'application/vnd.openxmlformats-officedocument.presentationml.presentation',
    'application/zip',
]

const acceptedExtensions = ['.png', '.jpg', '.jpeg', '.ppt', '.pptx', '.zip']

const isUploading = computed(() => uploading.value)
const progressPercent = computed(() => Math.round(uploadProgress.value))

function processFiles() {
    if (files.value.length === 0) return

    uploadError.value = ''
    totalCount.value = files.value.length
    uploadedCount.value = 0
    uploading.value = true
    uploadProgress.value = 0

    uploadNextFile(0)
}

function uploadNextFile(index) {
    if (index >= files.value.length) {
        uploading.value = false
        uploadProgress.value = 100
        files.value = []
        emit('uploaded')

        // Reset progress after brief display
        setTimeout(() => {
            uploadProgress.value = 0
            uploadedCount.value = 0
            totalCount.value = 0
        }, 2000)
        return
    }

    const file = files.value[index]

    // Validate extension client-side
    const ext = '.' + file.name.split('.').pop().toLowerCase()
    if (!acceptedExtensions.includes(ext)) {
        uploadError.value = `"${file.name}" — Dateityp nicht erlaubt. Nur PNG, JPG, PPT, PPTX und ZIP.`
        uploading.value = false
        return
    }

    const formData = new FormData()
    formData.append('file', file)
    formData.append('type', props.type)

    if (props.serviceId) {
        formData.append('service_id', props.serviceId)
    }

    if (props.showExpireDate && expireDate.value) {
        formData.append('expire_date', expireDate.value)
    }

    router.post(route('slides.store'), formData, {
        forceFormData: true,
        preserveScroll: true,
        preserveState: true,
        onProgress: (event) => {
            if (event.percentage) {
                // Per-file progress weighted across total
                const perFileWeight = 100 / totalCount.value
                uploadProgress.value = (index * perFileWeight) + (event.percentage / 100 * perFileWeight)
            }
        },
        onSuccess: () => {
            uploadedCount.value = index + 1
            uploadNextFile(index + 1)
        },
        onError: (errors) => {
            uploading.value = false
            uploadError.value = errors.file?.[0] || errors.message || 'Upload fehlgeschlagen.'
        },
    })
}

function dismissError() {
    uploadError.value = ''
}
</script>

<template>
    <div data-testid="slide-uploader" class="slide-uploader">
        <!-- Expire date picker for information slides -->
        <div
            v-if="showExpireDate"
            class="mb-4 flex items-center gap-3"
        >
            <label class="text-sm font-medium text-gray-600">
                Ablaufdatum für neue Folien
            </label>
            <input
                data-testid="slide-uploader-expire-input"
                v-model="expireDate"
                type="date"
                class="rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-sm text-gray-700 shadow-sm transition focus:border-amber-400 focus:outline-none focus:ring-2 focus:ring-amber-400/30"
            />
        </div>

        <!-- Error message -->
        <Transition
            enter-active-class="transition duration-200 ease-out"
            enter-from-class="opacity-0 -translate-y-1"
            enter-to-class="opacity-100 translate-y-0"
            leave-active-class="transition duration-150 ease-in"
            leave-from-class="opacity-100 translate-y-0"
            leave-to-class="opacity-0 -translate-y-1"
        >
            <div
                v-if="uploadError"
                class="mb-4 flex items-center gap-3 rounded-xl border border-red-200 bg-red-50/80 px-4 py-3 text-sm text-red-700"
            >
                <svg class="h-5 w-5 shrink-0 text-red-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z" />
                </svg>
                <span class="flex-1">{{ uploadError }}</span>
                <button
                    data-testid="slide-uploader-error-dismiss"
                    @click="dismissError"
                    class="shrink-0 rounded-lg p-0.5 text-red-400 transition hover:text-red-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>
            </div>
        </Transition>

        <!-- Upload progress bar -->
        <Transition
            enter-active-class="transition duration-300 ease-out"
            enter-from-class="opacity-0 scale-95"
            enter-to-class="opacity-100 scale-100"
            leave-active-class="transition duration-200 ease-in"
            leave-from-class="opacity-100 scale-100"
            leave-to-class="opacity-0 scale-95"
        >
            <div
                v-if="isUploading || (uploadProgress > 0 && uploadProgress <= 100)"
                class="mb-4"
            >
                <div class="flex items-center justify-between text-xs text-gray-500 mb-1.5">
                    <span class="font-medium">
                        Hochladen... {{ uploadedCount }}/{{ totalCount }}
                    </span>
                    <span class="tabular-nums">{{ progressPercent }}%</span>
                </div>
                <div class="h-2 w-full overflow-hidden rounded-full bg-gray-100">
                    <div
                        class="h-full rounded-full bg-gradient-to-r from-amber-400 to-orange-500 transition-all duration-500 ease-out"
                        :style="{ width: `${progressPercent}%` }"
                    />
                </div>
            </div>
        </Transition>

        <!-- Dropzone -->
        <Vue3Dropzone
            data-testid="slide-uploader-dropzone"
            v-model="files"
            :multiple="true"
            :accept="acceptedTypes"
            :max-file-size="50"
            :max-files="20"
            :disabled="isUploading"
            :show-select-button="false"
            class="slide-dropzone"
            @change="processFiles"
        >
            <template #placeholder-img>
                <div class="flex flex-col items-center gap-3 pointer-events-none">
                    <!-- Big plus icon -->
                    <div class="relative">
                        <div class="flex h-16 w-16 items-center justify-center rounded-2xl bg-gradient-to-br from-amber-50 to-orange-50 shadow-sm ring-1 ring-amber-200/60">
                            <svg class="h-8 w-8 text-amber-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
                            </svg>
                        </div>
                        <!-- Animated pulse ring -->
                        <div class="absolute inset-0 rounded-2xl ring-2 ring-amber-300/20 animate-ping" style="animation-duration: 3s;" />
                    </div>
                </div>
            </template>

            <template #title>
                <span class="mt-3 block text-sm font-semibold text-gray-700">
                    Dateien hier ablegen
                </span>
            </template>

            <template #description>
                <span class="mt-1 block text-xs text-gray-400">
                    oder klicken zum Auswählen
                </span>
                <span class="mt-2 block text-[11px] text-gray-300">
                    PNG, JPG, PPT, PPTX, ZIP — max 50 MB
                </span>
            </template>
        </Vue3Dropzone>
    </div>
</template>

<style scoped>
.slide-dropzone {
    --v3-dropzone--primary: 245, 158, 11;
    --v3-dropzone--border: 229, 231, 235;
    --v3-dropzone--description: 156, 163, 175;
    --v3-dropzone--overlay: 245, 158, 11;
    --v3-dropzone--overlay-opacity: 0.08;
}

.slide-dropzone :deep(.v3-dropzone) {
    border: 2px dashed rgb(229 231 235);
    border-radius: 1rem;
    background: linear-gradient(135deg, rgb(255 251 235 / 0.5), rgb(254 243 199 / 0.3));
    padding: 2rem 1.5rem;
    min-height: 160px;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    cursor: pointer;
}

.slide-dropzone :deep(.v3-dropzone:hover) {
    border-color: rgb(251 191 36);
    background: linear-gradient(135deg, rgb(255 251 235 / 0.8), rgb(254 243 199 / 0.5));
    box-shadow: 0 0 0 4px rgb(251 191 36 / 0.1);
}

.slide-dropzone :deep(.v3-dropzone.v3-dropzone--active) {
    border-color: rgb(245 158 11);
    background: linear-gradient(135deg, rgb(255 251 235), rgb(254 243 199 / 0.7));
    box-shadow: 0 0 0 4px rgb(245 158 11 / 0.15);
    transform: scale(1.01);
}

.slide-dropzone :deep(.v3-dropzone--disabled) {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Hide the default preview since we handle it in SlideGrid */
.slide-dropzone :deep(.v3-dropzone__preview) {
    display: none;
}
</style>
