<script setup>
import AppLayout from '@/layouts/AppLayout.vue'
import { ref, computed, getCurrentInstance } from 'vue'

const { proxy } = getCurrentInstance()

const step = ref(1)               // 1 = Upload, 2 = Platzieren
const previewLoading = ref(false)
const signLoading = ref(false)

const pdfFile = ref(null)
const signaturFile = ref(null)
const signaturUrl = ref('')
const stempelFile = ref(null)      // optional
const stempelUrl = ref('')

const dragPdf = ref(false)
const dragSig = ref(false)
const dragStempel = ref(false)

const IMAGE_TYPES = ['image/png', 'image/jpeg', 'image/webp']

const pages = ref([])             // [{ dataUri, width, height }]
const selectedPage = ref(1)       // 1-basiert
const graustufen = ref(true)

// Platzierung relativ zur Seite (0..1)
const placement = ref({ xFrac: 0.55, yFrac: 0.8, widthFrac: 0.25 })
const stempelPlacement = ref({ xFrac: 0.15, yFrac: 0.78, widthFrac: 0.18 })

const stageRef = ref(null)

const currentPage = computed(() => pages.value[selectedPage.value - 1] ?? null)
const canPreview = computed(() => pdfFile.value && signaturFile.value)

function csrf() {
    return document.querySelector('meta[name="csrf-token"]')?.content ?? ''
}

function setPdf(file) {
    if (!file) return
    if (file.type !== 'application/pdf') {
        proxy.$toast.error('Bitte eine PDF-Datei auswählen.')
        return
    }
    pdfFile.value = file
}

function setSignatur(file) {
    if (!file) return
    if (!IMAGE_TYPES.includes(file.type)) {
        proxy.$toast.error('Bitte ein Bild (PNG, JPG oder WebP) auswählen.')
        return
    }
    signaturFile.value = file
    if (signaturUrl.value) URL.revokeObjectURL(signaturUrl.value)
    signaturUrl.value = URL.createObjectURL(file)
}

function setStempel(file) {
    if (!file) return
    if (!IMAGE_TYPES.includes(file.type)) {
        proxy.$toast.error('Bitte ein Bild (PNG, JPG oder WebP) auswählen.')
        return
    }
    stempelFile.value = file
    if (stempelUrl.value) URL.revokeObjectURL(stempelUrl.value)
    stempelUrl.value = URL.createObjectURL(file)
}

function removeStempel() {
    stempelFile.value = null
    if (stempelUrl.value) URL.revokeObjectURL(stempelUrl.value)
    stempelUrl.value = ''
}

function onPdfChange(e) {
    setPdf(e.target.files[0] ?? null)
}

function onSignaturChange(e) {
    setSignatur(e.target.files[0] ?? null)
}

function onStempelChange(e) {
    setStempel(e.target.files[0] ?? null)
}

function onDropPdf(e) {
    dragPdf.value = false
    setPdf(e.dataTransfer.files[0] ?? null)
}

function onDropSig(e) {
    dragSig.value = false
    setSignatur(e.dataTransfer.files[0] ?? null)
}

function onDropStempel(e) {
    dragStempel.value = false
    setStempel(e.dataTransfer.files[0] ?? null)
}

async function loadPreview() {
    if (!canPreview.value) return
    previewLoading.value = true
    try {
        const data = new FormData()
        data.append('pdf', pdfFile.value)
        const res = await fetch('/unterschrift/preview', {
            method: 'POST',
            headers: { 'X-CSRF-TOKEN': csrf() },
            body: data,
        })
        if (!res.ok) {
            if (res.status === 413) {
                proxy.$toast.error('Die PDF-Datei ist zu groß.')
                return
            }
            const err = await res.json().catch(() => ({}))
            proxy.$toast.error(err.message ?? 'Die Vorschau konnte nicht erstellt werden.')
            return
        }
        const json = await res.json()
        pages.value = json.pages
        selectedPage.value = 1
        step.value = 2
    } catch {
        proxy.$toast.error('Netzwerkfehler beim Erstellen der Vorschau.')
    } finally {
        previewLoading.value = false
    }
}

// ── Drag von Unterschrift/Stempel ──
let dragState = null

function placementFor(which) {
    return which === 'stempel' ? stempelPlacement : placement
}

function startDrag(e, which) {
    const rect = stageRef.value.getBoundingClientRect()
    const p = placementFor(which).value
    dragState = {
        which,
        startX: e.clientX,
        startY: e.clientY,
        origX: p.xFrac,
        origY: p.yFrac,
        w: rect.width,
        h: rect.height,
    }
    window.addEventListener('pointermove', onDrag)
    window.addEventListener('pointerup', endDrag)
}

function onDrag(e) {
    if (!dragState) return
    const p = placementFor(dragState.which).value
    const dx = (e.clientX - dragState.startX) / dragState.w
    const dy = (e.clientY - dragState.startY) / dragState.h
    p.xFrac = clamp(dragState.origX + dx, 0, 1 - p.widthFrac * 0.2)
    p.yFrac = clamp(dragState.origY + dy, 0, 0.99)
}

function endDrag() {
    dragState = null
    window.removeEventListener('pointermove', onDrag)
    window.removeEventListener('pointerup', endDrag)
}

function clamp(v, min, max) {
    return Math.max(min, Math.min(max, v))
}

async function submitSign() {
    signLoading.value = true
    try {
        const data = new FormData()
        data.append('pdf', pdfFile.value)
        data.append('signatur', signaturFile.value)
        data.append('page', selectedPage.value)
        data.append('xFrac', placement.value.xFrac)
        data.append('yFrac', placement.value.yFrac)
        data.append('widthFrac', placement.value.widthFrac)
        data.append('graustufen', graustufen.value ? '1' : '0')

        if (stempelFile.value) {
            data.append('stempel', stempelFile.value)
            data.append('stempelXFrac', stempelPlacement.value.xFrac)
            data.append('stempelYFrac', stempelPlacement.value.yFrac)
            data.append('stempelWidthFrac', stempelPlacement.value.widthFrac)
        }

        const res = await fetch('/unterschrift/sign', {
            method: 'POST',
            headers: { 'X-CSRF-TOKEN': csrf() },
            body: data,
        })
        if (!res.ok) {
            if (res.status === 413) {
                proxy.$toast.error('Die hochgeladenen Dateien sind zu groß.')
                return
            }
            const err = await res.json().catch(() => ({}))
            proxy.$toast.error(err.message ?? 'Das Dokument konnte nicht signiert werden.')
            return
        }
        const blob = await res.blob()
        window.open(URL.createObjectURL(blob), '_blank')
    } catch {
        proxy.$toast.error('Netzwerkfehler beim Signieren.')
    } finally {
        signLoading.value = false
    }
}

function reset() {
    step.value = 1
    pages.value = []
}
</script>

<template>
    <AppLayout title="Dokument unterschreiben">
        <div class="page">

            <!-- Breadcrumb -->
            <div class="page-header">
                <nav class="breadcrumb">
                    <a href="/" class="bc-link">Startseite</a>
                    <font-awesome-icon icon="chevron-right" class="bc-sep" />
                    <span class="bc-current">Dokument unterschreiben</span>
                </nav>
            </div>

            <!-- Titel -->
            <div class="page-title">
                <div class="title-icon">
                    <font-awesome-icon icon="signature" />
                </div>
                <div>
                    <h1 class="title-text">Dokument unterschreiben</h1>
                    <p class="title-sub">
                        PDF und Unterschrift hochladen, platzieren und als „eingescanntes" Dokument herunterladen.
                    </p>
                </div>
            </div>

            <!-- ── SCHRITT 1: Upload ── -->
            <div v-if="step === 1" class="card upload-card">
                <h2 class="card-heading">Dateien auswählen</h2>

                <div class="field">
                    <label class="label">PDF-Dokument</label>
                    <label
                        class="dropzone"
                        :class="{ 'dropzone--active': dragPdf, 'dropzone--filled': pdfFile }"
                        @dragover.prevent="dragPdf = true"
                        @dragenter.prevent="dragPdf = true"
                        @dragleave.prevent="dragPdf = false"
                        @drop.prevent="onDropPdf"
                    >
                        <input type="file" accept="application/pdf" class="dropzone-input" @change="onPdfChange" />
                        <font-awesome-icon icon="file-pdf" class="dropzone-icon" />
                        <span v-if="pdfFile" class="dropzone-file">{{ pdfFile.name }}</span>
                        <span v-else class="dropzone-hint">
                            PDF hierher ziehen oder <span class="dropzone-link">durchsuchen</span>
                        </span>
                    </label>
                </div>

                <div class="field">
                    <label class="label">Unterschrift (Foto oder Scan, PNG/JPG)</label>
                    <label
                        class="dropzone"
                        :class="{ 'dropzone--active': dragSig, 'dropzone--filled': signaturFile }"
                        @dragover.prevent="dragSig = true"
                        @dragenter.prevent="dragSig = true"
                        @dragleave.prevent="dragSig = false"
                        @drop.prevent="onDropSig"
                    >
                        <input type="file" accept="image/png,image/jpeg,image/webp" class="dropzone-input" @change="onSignaturChange" />
                        <template v-if="signaturUrl">
                            <div class="sig-preview">
                                <img :src="signaturUrl" alt="Unterschrift" />
                            </div>
                            <span class="dropzone-file">{{ signaturFile.name }}</span>
                        </template>
                        <template v-else>
                            <font-awesome-icon icon="signature" class="dropzone-icon" />
                            <span class="dropzone-hint">
                                Bild hierher ziehen oder <span class="dropzone-link">durchsuchen</span>
                            </span>
                        </template>
                    </label>
                </div>

                <div class="field">
                    <label class="label">
                        Stempel <span class="optional">(optional)</span>
                    </label>
                    <label
                        class="dropzone"
                        :class="{ 'dropzone--active': dragStempel, 'dropzone--filled': stempelFile }"
                        @dragover.prevent="dragStempel = true"
                        @dragenter.prevent="dragStempel = true"
                        @dragleave.prevent="dragStempel = false"
                        @drop.prevent="onDropStempel"
                    >
                        <input type="file" accept="image/png,image/jpeg,image/webp" class="dropzone-input" @change="onStempelChange" />
                        <template v-if="stempelUrl">
                            <div class="sig-preview">
                                <img :src="stempelUrl" alt="Stempel" />
                            </div>
                            <span class="dropzone-file">{{ stempelFile.name }}</span>
                            <button type="button" class="dropzone-remove" @click.prevent.stop="removeStempel">
                                <font-awesome-icon icon="trash" /> Entfernen
                            </button>
                        </template>
                        <template v-else>
                            <font-awesome-icon icon="stamp" class="dropzone-icon" />
                            <span class="dropzone-hint">
                                Stempel hierher ziehen oder <span class="dropzone-link">durchsuchen</span>
                            </span>
                        </template>
                    </label>
                </div>

                <button class="btn-primary" :disabled="!canPreview || previewLoading" @click="loadPreview">
                    <font-awesome-icon :icon="previewLoading ? 'file-invoice' : 'chevron-right'" />
                    {{ previewLoading ? 'Vorschau wird erstellt…' : 'Weiter: Platzieren' }}
                </button>
            </div>

            <!-- ── SCHRITT 2: Platzieren ── -->
            <div v-else class="sign-grid">

                <!-- Steuerung -->
                <div class="card">
                    <h2 class="card-heading">Platzierung</h2>

                    <div class="field" v-if="pages.length > 1">
                        <label class="label">Seite</label>
                        <div class="page-badges">
                            <button
                                v-for="n in pages.length"
                                :key="n"
                                class="page-badge"
                                :class="{ 'page-badge--active': selectedPage === n }"
                                @click="selectedPage = n"
                            >{{ n }}</button>
                        </div>
                        <p class="hint">Die Unterschrift wird auf Seite {{ selectedPage }} eingefügt.</p>
                    </div>

                    <div class="field">
                        <label class="label">Größe der Unterschrift</label>
                        <input
                            type="range" min="0.05" max="0.6" step="0.01"
                            v-model.number="placement.widthFrac" class="range"
                        />
                    </div>

                    <div class="field" v-if="stempelFile">
                        <label class="label">Größe des Stempels</label>
                        <input
                            type="range" min="0.05" max="0.6" step="0.01"
                            v-model.number="stempelPlacement.widthFrac" class="range"
                        />
                    </div>

                    <label class="check-row">
                        <input type="checkbox" v-model="graustufen" />
                        <span>Graustufen (Scan-Look)</span>
                    </label>

                    <p class="hint">
                        Ziehe die Unterschrift<template v-if="stempelFile"> und den Stempel</template>
                        im Vorschaubild an die gewünschte Stelle.
                    </p>

                    <div class="btn-col">
                        <button class="btn-primary" :disabled="signLoading" @click="submitSign">
                            <font-awesome-icon :icon="signLoading ? 'file-invoice' : 'download'" />
                            {{ signLoading ? 'Wird erstellt…' : 'Signieren & herunterladen' }}
                        </button>
                        <button class="btn-back" @click="reset">
                            <font-awesome-icon icon="chevron-left" />
                            Zurück
                        </button>
                    </div>
                </div>

                <!-- Vorschau mit Overlay -->
                <div class="card preview-card">
                    <div class="stage-wrap">
                        <div ref="stageRef" class="stage" v-if="currentPage">
                            <img class="stage-page" :src="currentPage.dataUri" alt="Seitenvorschau" draggable="false" />
                            <img
                                v-if="stempelUrl"
                                class="stage-overlay stage-stempel"
                                :src="stempelUrl"
                                alt="Stempel"
                                draggable="false"
                                :style="{
                                    left: (stempelPlacement.xFrac * 100) + '%',
                                    top: (stempelPlacement.yFrac * 100) + '%',
                                    width: (stempelPlacement.widthFrac * 100) + '%',
                                }"
                                @pointerdown.prevent="startDrag($event, 'stempel')"
                            />
                            <img
                                v-if="signaturUrl"
                                class="stage-overlay stage-sig"
                                :src="signaturUrl"
                                alt="Unterschrift"
                                draggable="false"
                                :style="{
                                    left: (placement.xFrac * 100) + '%',
                                    top: (placement.yFrac * 100) + '%',
                                    width: (placement.widthFrac * 100) + '%',
                                }"
                                @pointerdown.prevent="startDrag($event, 'sig')"
                            />
                        </div>
                    </div>
                </div>

            </div>

        </div>
    </AppLayout>
</template>

<style scoped>
.page { display: flex; flex-direction: column; gap: 20px; }

/* Breadcrumb */
.page-header { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.breadcrumb { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; color: #6b7280; }
.bc-link { color: #1d4899; text-decoration: none; }
.bc-link:hover { text-decoration: underline; }
.bc-sep { font-size: 0.7rem; color: #9ca3af; }
.bc-current { color: #374151; font-weight: 500; }

/* Titel */
.page-title { display: flex; align-items: center; gap: 14px; }
.title-icon {
    width: 44px; height: 44px; background: #eef2ff; color: #1d4899;
    border-radius: 10px; display: flex; align-items: center; justify-content: center;
    font-size: 1.2rem; flex-shrink: 0;
}
.title-text { margin: 0 0 3px; font-size: 1.25rem; font-weight: 700; color: #111827; }
.title-sub { margin: 0; font-size: 0.85rem; color: #6b7280; }

/* Karte */
.card {
    background: white; border-radius: 12px; box-shadow: 0 1px 4px rgba(0,0,0,0.07);
    padding: 24px; border: 1px solid #f0f0f0;
}
.card-heading { margin: 0 0 18px; font-size: 1rem; font-weight: 700; color: #111827; }

.upload-card { max-width: 560px; display: flex; flex-direction: column; gap: 18px; }

.field { display: flex; flex-direction: column; gap: 6px; }
.label { font-size: 0.8rem; font-weight: 600; color: #374151; }

.dropzone {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 8px; text-align: center;
    min-height: 120px; padding: 18px;
    border: 2px dashed #d1d5db; border-radius: 10px;
    background: #fafafa; cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}
.dropzone:hover { border-color: #1d4899; background: #f5f7fd; }
.dropzone--active { border-color: #1d4899; background: #eef2ff; }
.dropzone--filled { border-style: solid; border-color: #c7d2fe; background: #fff; }

.dropzone-input {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0; cursor: pointer;
}
.dropzone-icon { font-size: 1.6rem; color: #9ca3af; }
.dropzone--filled .dropzone-icon { color: #1d4899; }
.dropzone-hint { font-size: 0.82rem; color: #6b7280; }
.dropzone-link { color: #1d4899; font-weight: 600; text-decoration: underline; }
.dropzone-file { font-size: 0.8rem; font-weight: 600; color: #374151; word-break: break-all; }
.dropzone-remove {
    display: inline-flex; align-items: center; gap: 6px;
    background: transparent; border: none; cursor: pointer;
    font-size: 0.76rem; color: #ef4444; padding: 2px 4px;
}
.dropzone-remove:hover { text-decoration: underline; }

.optional { font-weight: 500; color: #9ca3af; }

.sig-preview {
    padding: 10px; border: 1px solid #f0f0f0; border-radius: 8px;
    background: repeating-conic-gradient(#f3f4f6 0% 25%, #fff 0% 50%) 0 / 16px 16px;
    max-width: 240px;
}
.sig-preview img { max-width: 100%; max-height: 90px; display: block; }

/* Buttons */
.btn-primary {
    display: flex; align-items: center; justify-content: center; gap: 9px;
    padding: 11px 16px; background: #1d4899; color: white; border: none;
    border-radius: 9px; font-size: 0.92rem; font-weight: 700; cursor: pointer;
    transition: background 0.15s;
}
.btn-primary:hover:not(:disabled) { background: #163a7a; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }

.btn-back {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    background: white; color: #374151; border: 1px solid #e5e7eb; border-radius: 8px;
    padding: 10px 16px; font-size: 0.88rem; font-weight: 600; cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.btn-back:hover { background: #f9fafb; border-color: #d1d5db; }

.btn-col { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }

/* Schritt 2 Layout */
.sign-grid { display: grid; grid-template-columns: 320px 1fr; gap: 20px; align-items: start; }

.page-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.page-badge {
    min-width: 34px; padding: 5px 10px; border: 1px solid #e5e7eb; border-radius: 7px;
    background: white; font-size: 0.82rem; font-weight: 600; color: #6b7280; cursor: pointer;
    transition: all 0.15s;
}
.page-badge:hover { border-color: #1d4899; color: #1d4899; }
.page-badge--active { background: #1d4899; border-color: #1d4899; color: white; }

.range { width: 100%; accent-color: #1d4899; }

.check-row { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; color: #374151; cursor: pointer; margin-top: 4px; }
.check-row input { accent-color: #1d4899; }

.hint { font-size: 0.78rem; color: #9ca3af; margin: 10px 0 0; line-height: 1.5; }

/* Vorschau-Bühne */
.preview-card { padding: 16px; background: #f5f6fa; }
.stage-wrap { display: flex; justify-content: center; }
.stage {
    position: relative; display: inline-block; max-width: 100%;
    box-shadow: 0 2px 10px rgba(0,0,0,0.12); background: white;
}
.stage-page { display: block; max-width: 100%; height: auto; user-select: none; }
.stage-overlay {
    position: absolute; cursor: grab; user-select: none;
    mix-blend-mode: multiply; touch-action: none;
}
.stage-overlay:active { cursor: grabbing; }
.stage-stempel { outline: 1px dashed rgba(29, 72, 153, 0.35); outline-offset: 2px; }

@media (max-width: 900px) {
    .sign-grid { grid-template-columns: 1fr; }
}
</style>
