<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { Eye, Handshake, Mic2, Plus, Save, Settings2, Trash2 } from '@lucide/vue'

import { privacyContentToHtml } from '../../lib/privacyContent'
import { useAwardsStore } from '../../stores/awards'
import type { AdminSponsorItem, UpsertSponsorPayload } from '../../types/awards'
import Button from '../ui/Button.vue'
import AdminContentFooterPreviewModal from './AdminContentFooterPreviewModal.vue'
import AdminRichTextEditor from './AdminRichTextEditor.vue'
import AdminSettingsToggle from './AdminSettingsToggle.vue'
import type { AdminContentForm } from './adminContentTypes'
import AdminShowactFormBuilder from './AdminShowactFormBuilder.vue'
import Modal from '../ui/Modal.vue'

const props = defineProps<{
  section: 'showacts' | 'sponsors'
  form: AdminContentForm
  saving: boolean
  saveSiteSettings: (sectionLabel?: string) => Promise<void>
}>()

const store = useAwardsStore()
const loading = ref(false)
const localSaving = ref(false)
const statusMessage = ref('')
const statusError = ref('')
const previewOpen = ref(false)
const previewHtml = computed(() => privacyContentToHtml(props.form.sponsorsContent))
const previewTitle = 'Sponsoren & Partner'
const editingSponsorId = ref<number | null>(null)
const selectedShowactId = ref<number | null>(null)
const showactNotes = reactive<Record<number, string>>({})
const settingsForm = reactive({
  showactApplicationsEnabled: false,
  showactApplicationStartsAt: '',
  showactApplicationEndsAt: '',
  showactApplicationsOpenNow: false,
  showactApplicationDisabledMessage: 'Showact-Bewerbungen sind aktuell geschlossen.',
  sponsorsVisible: true,
})
const sponsorForm = reactive<UpsertSponsorPayload>({
  name: '',
  websiteUrl: '',
  logoUrl: '',
  description: '',
  tier: 'Partner',
  sortOrder: 0,
  isVisible: true,
})

const seasonId = computed(() => store.adminSelectedSeasonId ?? (store.adminSeasonDetail.id || store.overview.seasonId))
const pendingShowacts = computed(() => store.adminShowactApplications.filter((item) => item.status === 'pending').length)
const visibleSponsors = computed(() => store.adminSponsors.filter((item) => item.isVisible).length)
const selectedShowact = computed(() =>
  selectedShowactId.value == null
    ? null
    : store.adminShowactApplications.find((item) => item.id === selectedShowactId.value) ?? null,
)

const showactSubmissionDetails = computed(() => {
  const application = selectedShowact.value
  if (!application) return []

  const schemaFields = props.form.showactFormSchema ?? []
  const responseEntries = parseShowactResponses(application.fieldResponsesJson)
  const responseMap = new Map(responseEntries)
  const consumedKeys = new Set<string>()

  const orderedFields = schemaFields
    .map((field) => {
      const value = normalizeDetailValue(responseMap.get(field.id))
      consumedKeys.add(field.id)
      if (!value) return null
      return {
        key: field.id,
        label: field.label,
        value,
      }
    })
    .filter((item): item is { key: string; label: string; value: string } => item !== null)

  const remainingFields = responseEntries
    .filter(([key]) => !consumedKeys.has(key))
    .map(([key, value]) => ({
      key,
      label: humanizeShowactKey(key),
      value: normalizeDetailValue(value),
    }))
    .filter((item) => item.value)

  if (orderedFields.length > 0 || remainingFields.length > 0) {
    return [...orderedFields, ...remainingFields]
  }

  return [
    { key: 'artistName', label: 'Artist', value: application.artistName },
    { key: 'performanceType', label: 'Performance', value: application.performanceType },
    { key: 'description', label: 'Beschreibung', value: application.description },
    { key: 'technicalNotes', label: 'Technische Hinweise', value: application.technicalNotes },
    { key: 'platformUrl', label: 'Kanal oder Profil', value: application.platformUrl },
    { key: 'referenceUrl', label: 'Referenz', value: application.referenceUrl },
    { key: 'contactEmail', label: 'E-Mail', value: application.contactEmail },
    { key: 'contactDiscord', label: 'Discord', value: application.contactDiscord },
  ].filter((item) => normalizeDetailValue(item.value))
})

watch(
  () => store.adminOptionalFeatureSettings,
  (settings) => {
    settingsForm.showactApplicationsEnabled = settings.showactApplicationsEnabled
    settingsForm.showactApplicationStartsAt = settings.showactApplicationStartsAt ?? ''
    settingsForm.showactApplicationEndsAt = settings.showactApplicationEndsAt ?? ''
    settingsForm.showactApplicationsOpenNow = settings.showactApplicationsOpenNow
    settingsForm.showactApplicationDisabledMessage = settings.showactApplicationDisabledMessage || 'Showact-Bewerbungen sind aktuell geschlossen.'
    settingsForm.sponsorsVisible = settings.sponsorsVisible
  },
  { immediate: true, deep: true },
)

const showactStatusText = computed(() => {
  if (!settingsForm.showactApplicationsEnabled) {
    return 'Bewerbungen sind manuell deaktiviert und es wird nur der Hinweistext ausgespielt.'
  }

  const parts: string[] = []
  if (settingsForm.showactApplicationStartsAt) {
    parts.push(`Start ${formatDate(settingsForm.showactApplicationStartsAt)}`)
  }
  if (settingsForm.showactApplicationEndsAt) {
    parts.push(`Deadline ${formatDate(settingsForm.showactApplicationEndsAt)}`)
  }

  if (settingsForm.showactApplicationsOpenNow) {
    return parts.length > 0
      ? `Bewerbungen sind aktuell offen. ${parts.join(' · ')}.`
      : 'Bewerbungen sind aktuell offen und das Modal bleibt für Einreichungen verfügbar.'
  }

  if (parts.length > 0) {
    return `Bewerbungen sind aktuell geschlossen. ${parts.join(' · ')}.`
  }

  return 'Bewerbungen sind aktuell geschlossen und es wird nur der Hinweistext ausgespielt.'
})

const showactScheduleError = computed(() => {
  if (!settingsForm.showactApplicationStartsAt || !settingsForm.showactApplicationEndsAt) {
    return ''
  }

  return settingsForm.showactApplicationStartsAt > settingsForm.showactApplicationEndsAt
    ? 'Der Starttermin darf nicht nach der Deadline liegen.'
    : ''
})

function resetSponsorForm() {
  editingSponsorId.value = null
  sponsorForm.name = ''
  sponsorForm.websiteUrl = ''
  sponsorForm.logoUrl = ''
  sponsorForm.description = ''
  sponsorForm.tier = 'Partner'
  sponsorForm.sortOrder = store.adminSponsors.length + 1
  sponsorForm.isVisible = true
}

function editSponsor(sponsor: AdminSponsorItem) {
  editingSponsorId.value = sponsor.id
  sponsorForm.name = sponsor.name
  sponsorForm.websiteUrl = sponsor.websiteUrl
  sponsorForm.logoUrl = sponsor.logoUrl
  sponsorForm.description = sponsor.description
  sponsorForm.tier = sponsor.tier
  sponsorForm.sortOrder = sponsor.sortOrder
  sponsorForm.isVisible = sponsor.isVisible
}

async function ensureSeasonId() {
  if (seasonId.value) return seasonId.value
  await store.loadHomeData()
  return store.overview.seasonId
}

async function loadLandingExtras() {
  loading.value = true
  statusError.value = ''
  try {
    const resolvedSeasonId = await ensureSeasonId()
    await Promise.all([
      store.loadAdminOptionalFeatureSettings(),
      resolvedSeasonId ? store.loadAdminExtras(resolvedSeasonId) : Promise.resolve(),
    ])
    for (const application of store.adminShowactApplications) {
      showactNotes[application.id] = application.reviewNote ?? ''
    }
    resetSponsorForm()
  } catch (error) {
    statusError.value = error instanceof Error ? error.message : 'Landingpage-Extras konnten nicht geladen werden.'
  } finally {
    loading.value = false
  }
}

async function saveAll() {
  localSaving.value = true
  statusMessage.value = ''
  statusError.value = ''
  try {
    if (showactScheduleError.value) {
      throw new Error(showactScheduleError.value)
    }

    await Promise.all([
      store.updateAdminOptionalFeatureSettings({
        clipSubmissionsEnabled: store.adminOptionalFeatureSettings.clipSubmissionsEnabled,
        clipReviewEnabled: store.adminOptionalFeatureSettings.clipReviewEnabled,
        clipAdminMenuVisible: store.adminOptionalFeatureSettings.clipAdminMenuVisible,
        clipSubmissionDisabledMessage: store.adminOptionalFeatureSettings.clipSubmissionDisabledMessage,
        showactApplicationsEnabled: settingsForm.showactApplicationsEnabled,
        showactApplicationStartsAt: settingsForm.showactApplicationStartsAt || null,
        showactApplicationEndsAt: settingsForm.showactApplicationEndsAt || null,
        showactApplicationDisabledMessage: settingsForm.showactApplicationDisabledMessage,
        sponsorsVisible: settingsForm.sponsorsVisible,
      }),
      props.saveSiteSettings(props.section === 'showacts' ? 'Showact-Inhalt' : 'Sponsoren-Inhalt'),
    ])
    statusMessage.value = 'Einstellungen gespeichert.'
  } catch (error) {
    statusError.value = error instanceof Error ? error.message : 'Einstellungen konnten nicht gespeichert werden.'
  } finally {
    localSaving.value = false
  }
}

async function saveSponsor() {
  const resolvedSeasonId = await ensureSeasonId()
  if (!resolvedSeasonId) return
  localSaving.value = true
  statusMessage.value = ''
  statusError.value = ''
  try {
    if (editingSponsorId.value) {
      await store.updateAdminSponsor(editingSponsorId.value, resolvedSeasonId, sponsorForm)
      statusMessage.value = 'Sponsor wurde aktualisiert.'
    } else {
      await store.createAdminSponsor(resolvedSeasonId, sponsorForm)
      statusMessage.value = 'Sponsor wurde angelegt.'
    }
    resetSponsorForm()
  } catch (error) {
    statusError.value = error instanceof Error ? error.message : 'Sponsor konnte nicht gespeichert werden.'
  } finally {
    localSaving.value = false
  }
}

async function deleteSponsor(sponsor: AdminSponsorItem) {
  const resolvedSeasonId = await ensureSeasonId()
  if (!resolvedSeasonId || !window.confirm(`Sponsor "${sponsor.name}" loeschen?`)) return
  localSaving.value = true
  statusMessage.value = ''
  statusError.value = ''
  try {
    await store.deleteAdminSponsor(sponsor.id, resolvedSeasonId)
    if (editingSponsorId.value === sponsor.id) resetSponsorForm()
    statusMessage.value = 'Sponsor wurde geloescht.'
  } catch (error) {
    statusError.value = error instanceof Error ? error.message : 'Sponsor konnte nicht geloescht werden.'
  } finally {
    localSaving.value = false
  }
}

async function updateShowactStatus(applicationId: number, status: string) {
  const resolvedSeasonId = await ensureSeasonId()
  if (!resolvedSeasonId) return
  localSaving.value = true
  statusMessage.value = ''
  statusError.value = ''
  try {
    await store.updateAdminShowactStatus(applicationId, resolvedSeasonId, {
      status,
      reviewNote: showactNotes[applicationId] ?? '',
    })
    statusMessage.value = 'Showact-Status wurde gespeichert.'
  } catch (error) {
    statusError.value = error instanceof Error ? error.message : 'Showact-Status konnte nicht gespeichert werden.'
  } finally {
    localSaving.value = false
  }
}

async function deleteShowact(applicationId: number, artistName: string) {
  const resolvedSeasonId = await ensureSeasonId()
  if (!resolvedSeasonId || !window.confirm(`Showact-Bewerbung von "${artistName}" loeschen?`)) return
  localSaving.value = true
  statusMessage.value = ''
  statusError.value = ''
  try {
    await store.deleteAdminShowactApplication(applicationId, resolvedSeasonId)
    delete showactNotes[applicationId]
    statusMessage.value = 'Showact-Bewerbung wurde geloescht.'
  } catch (error) {
    statusError.value = error instanceof Error ? error.message : 'Showact-Bewerbung konnte nicht geloescht werden.'
  } finally {
    localSaving.value = false
  }
}

function statusLabel(status: string) {
  return {
    pending: 'Offen',
    shortlisted: 'Shortlist',
    accepted: 'Angenommen',
    rejected: 'Abgelehnt',
  }[status] ?? status
}

function formatDate(value: string) {
  const parsed = new Date(`${value}T00:00:00`)
  return Number.isNaN(parsed.getTime())
    ? value
    : parsed.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })
}

function parseShowactResponses(raw: string) {
  try {
    const parsed = JSON.parse(raw)
    if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
      return [] as Array<[string, unknown]>
    }

    return Object.entries(parsed)
  } catch {
    return [] as Array<[string, unknown]>
  }
}

function normalizeDetailValue(value: unknown) {
  if (Array.isArray(value)) {
    return value
      .map((item) => String(item).trim())
      .filter(Boolean)
      .join(', ')
  }

  if (typeof value === 'boolean') {
    return value ? 'Ja' : 'Nein'
  }

  if (value == null) {
    return ''
  }

  return String(value).trim()
}

function humanizeShowactKey(key: string) {
  return key
    .replace(/_/g, ' ')
    .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
    .replace(/\s+/g, ' ')
    .trim()
    .replace(/^./, (char) => char.toUpperCase())
}

function openShowactDetails(applicationId: number) {
  selectedShowactId.value = applicationId
}

function closeShowactDetails() {
  selectedShowactId.value = null
}

onMounted(loadLandingExtras)
</script>

<template>
  <div class="space-y-6">
    <div class="flex items-center justify-between gap-4">
      <p class="text-sm text-slate-500">
        <template v-if="props.section === 'showacts'">
          {{ store.adminShowactApplications.length }} Bewerbungen · {{ pendingShowacts }} offen
        </template>
        <template v-else>
          {{ store.adminSponsors.length }} Sponsoren · {{ visibleSponsors }} sichtbar
        </template>
      </p>
      <Button variant="ghost" size="sm" class="gap-2 rounded-2xl border border-violet-200 bg-white px-4 text-violet-700 shadow-none hover:bg-violet-50" :disabled="loading" @click="loadLandingExtras">
        <Settings2 class="h-4 w-4" />
        {{ loading ? 'Laedt ...' : 'Neu laden' }}
      </Button>
    </div>

    <!-- Showacts section -->
    <template v-if="props.section === 'showacts'">
      <div class="rounded-2xl border border-violet-100 bg-white p-4">
        <div class="flex items-start justify-between gap-4">
          <div>
            <h3 class="text-base font-bold text-slate-900">Showact-Bewerbung</h3>
            <p class="mt-1 text-sm leading-6 text-slate-500">
              {{ showactStatusText }}
            </p>
          </div>
          <AdminSettingsToggle
            :model-value="settingsForm.showactApplicationsEnabled"
            label="Showact-Bewerbungen aktivieren"
            active-label="Bewerbung offen"
            inactive-label="Bewerbung geschlossen"
            @update:model-value="settingsForm.showactApplicationsEnabled = $event"
          />
        </div>
      </div>

      <div class="grid gap-4 md:grid-cols-2">
        <label class="block space-y-2">
          <span class="text-sm font-bold text-slate-900">Starttermin (optional)</span>
          <input
            v-model="settingsForm.showactApplicationStartsAt"
            type="date"
            class="h-12 w-full rounded-2xl border border-violet-100 bg-white px-4 text-sm text-slate-700 outline-none transition focus:border-violet-300 focus:ring-4 focus:ring-violet-100"
          />
        </label>

        <label class="block space-y-2">
          <span class="text-sm font-bold text-slate-900">Deadline (optional)</span>
          <input
            v-model="settingsForm.showactApplicationEndsAt"
            type="date"
            class="h-12 w-full rounded-2xl border border-violet-100 bg-white px-4 text-sm text-slate-700 outline-none transition focus:border-violet-300 focus:ring-4 focus:ring-violet-100"
          />
        </label>
      </div>

      <p v-if="showactScheduleError" class="text-sm font-semibold text-rose-700">
        {{ showactScheduleError }}
      </p>

      <label class="block space-y-2">
        <span class="text-sm font-bold text-slate-900">Hinweis bei geschlossenen Bewerbungen</span>
        <textarea
          v-model="settingsForm.showactApplicationDisabledMessage"
          rows="3"
          maxlength="240"
          class="w-full rounded-2xl border border-violet-100 bg-white px-4 py-3 text-sm leading-6 text-slate-700 outline-none transition focus:border-violet-300 focus:ring-4 focus:ring-violet-100"
        />
      </label>

      <div class="flex flex-wrap items-center gap-3">
        <Button class="gap-2" :disabled="props.saving || localSaving" @click="saveAll">
          <Save class="h-4 w-4" />
          {{ (props.saving || localSaving) ? 'Speichert ...' : 'Einstellungen speichern' }}
        </Button>
        <p v-if="statusMessage" class="text-sm font-semibold text-emerald-700">{{ statusMessage }}</p>
        <p v-if="statusError" class="text-sm font-semibold text-rose-700">{{ statusError }}</p>
      </div>

      <AdminShowactFormBuilder
        :form="props.form"
        :saving="props.saving"
        :save-site-settings="props.saveSiteSettings"
      />

      <div class="overflow-hidden rounded-2xl border border-violet-100 bg-white">
        <div class="border-b border-violet-100 p-4">
          <div class="flex items-center gap-2">
            <Mic2 class="h-5 w-5 text-fuchsia-700" />
            <h3 class="text-base font-bold text-slate-900">Showact-Bewerbungen</h3>
          </div>
        </div>
        <div v-if="store.adminShowactApplications.length === 0" class="p-4 text-sm text-slate-500">
          Noch keine Bewerbungen für dieses Jahr.
        </div>
        <div v-else class="divide-y divide-violet-100">
          <article v-for="application in store.adminShowactApplications" :key="application.id" class="space-y-3 p-4">
            <div class="flex flex-wrap items-start justify-between gap-3">
              <div>
                <div class="flex flex-wrap items-center gap-2">
                  <h4 class="font-bold text-slate-950">{{ application.artistName }}</h4>
                  <span class="rounded-full bg-fuchsia-100 px-3 py-1 text-xs font-bold text-fuchsia-700">{{ statusLabel(application.status) }}</span>
                </div>
                <p class="mt-1 text-sm text-slate-500">{{ application.performanceType }}</p>
              </div>
              <div class="flex flex-wrap gap-2">
                <Button size="sm" variant="ghost" :disabled="saving" @click="openShowactDetails(application.id)">Details</Button>
                <Button size="sm" :disabled="saving" @click="updateShowactStatus(application.id, 'accepted')">Annehmen</Button>
                <Button size="sm" variant="secondary" :disabled="saving" @click="updateShowactStatus(application.id, 'rejected')">Ablehnen</Button>
                <Button size="sm" variant="ghost" class="text-rose-700" :disabled="saving" @click="deleteShowact(application.id, application.artistName)">
                  <Trash2 class="h-4 w-4" />
                </Button>
              </div>
            </div>

            <!-- Dynamic field responses if available, otherwise legacy fixed fields -->
            <template v-if="application.fieldResponsesJson && application.fieldResponsesJson !== '{}'">
              <div class="grid gap-2 text-sm text-slate-600 md:grid-cols-2">
                <template v-for="(value, key) in (() => { try { return JSON.parse(application.fieldResponsesJson) } catch { return {} } })()" :key="key">
                  <div v-if="value" class="flex flex-col gap-0.5">
                    <span class="text-xs font-bold uppercase tracking-wide text-slate-400">{{ key }}</span>
                    <span>{{ value }}</span>
                  </div>
                </template>
              </div>
            </template>
            <template v-else>
              <p class="text-sm leading-6 text-slate-600">{{ application.description }}</p>
              <div class="grid gap-2 text-sm text-slate-500 md:grid-cols-2">
                <a v-if="application.platformUrl" class="font-semibold text-violet-700 hover:text-violet-900" :href="application.platformUrl" target="_blank" rel="noreferrer">Kanal/Profil</a>
                <a v-if="application.referenceUrl" class="font-semibold text-violet-700 hover:text-violet-900" :href="application.referenceUrl" target="_blank" rel="noreferrer">Referenz</a>
                <span v-if="application.contactEmail">Mail: {{ application.contactEmail }}</span>
                <span v-if="application.contactDiscord">Discord: {{ application.contactDiscord }}</span>
              </div>
            </template>

            <textarea
              v-model="showactNotes[application.id]"
              rows="2"
              maxlength="500"
              placeholder="Interne Review-Notiz"
              class="w-full rounded-2xl border border-violet-100 bg-white px-4 py-3 text-sm outline-none focus:border-violet-300 focus:ring-4 focus:ring-violet-100"
            />
          </article>
        </div>
      </div>
    </template>

    <!-- Sponsors section -->
    <template v-else>
      <div class="rounded-2xl border border-violet-100 bg-white p-4">
        <div class="flex items-start justify-between gap-4">
          <div>
            <h3 class="text-base font-bold text-slate-900">Sponsoren-Modul</h3>
            <p class="mt-1 text-sm leading-6 text-slate-500">Sponsor-Kacheln auf der Landingpage anzeigen. Der Footer-Link "Sponsoren &amp; Partner" öffnet den unten gepflegten Modal-Inhalt.</p>
          </div>
          <AdminSettingsToggle
            :model-value="settingsForm.sponsorsVisible"
            label="Sponsoren anzeigen"
            active-label="Sichtbar"
            inactive-label="Aus"
            @update:model-value="settingsForm.sponsorsVisible = $event"
          />
        </div>
      </div>

      <div class="flex justify-end">
        <Button variant="ghost" size="sm" class="gap-2 rounded-2xl border border-violet-200 bg-violet-50 px-4 text-violet-700 shadow-none hover:bg-violet-100" @click="previewOpen = true">
          <Eye class="h-4 w-4" />
          Preview öffnen
        </Button>
      </div>
      <AdminRichTextEditor
        v-model="props.form.sponsorsContent"
        label="Footer-Modal: Sponsoren & Partner"
        placeholder="Texte für das Footer-Modal Sponsoren & Partner auf der Landingpage..."
        min-height-class="min-h-[220px]"
      />

      <div class="flex flex-wrap items-center gap-3">
        <Button class="gap-2" :disabled="props.saving || localSaving" @click="saveAll">
          <Save class="h-4 w-4" />
          {{ (props.saving || localSaving) ? 'Speichert ...' : 'Einstellungen speichern' }}
        </Button>
        <p v-if="statusMessage" class="text-sm font-semibold text-emerald-700">{{ statusMessage }}</p>
        <p v-if="statusError" class="text-sm font-semibold text-rose-700">{{ statusError }}</p>
      </div>

      <div class="overflow-hidden rounded-2xl border border-violet-100 bg-white">
        <div class="border-b border-violet-100 p-4">
          <div class="flex items-center gap-2">
            <Handshake class="h-5 w-5 text-sky-700" />
            <h3 class="text-base font-bold text-slate-900">Sponsoren</h3>
          </div>
        </div>

        <form class="space-y-3 p-4" @submit.prevent="saveSponsor">
          <div
            v-if="editingSponsorId"
            class="rounded-2xl border border-sky-100 bg-sky-50 px-4 py-3 text-sm font-semibold text-sky-800"
          >
            Bearbeitungsmodus aktiv. Deine Anpassungen werden beim Speichern direkt auf diesen Sponsor uebernommen.
          </div>
          <input v-model="sponsorForm.name" required maxlength="120" placeholder="Sponsor-Name" class="w-full rounded-2xl border border-violet-100 px-4 py-3 text-sm outline-none focus:border-violet-300 focus:ring-4 focus:ring-violet-100" />
          <div class="grid gap-3 sm:grid-cols-2">
            <input v-model="sponsorForm.websiteUrl" maxlength="500" placeholder="Website URL" class="rounded-2xl border border-violet-100 px-4 py-3 text-sm outline-none focus:border-violet-300 focus:ring-4 focus:ring-violet-100" />
            <input v-model="sponsorForm.logoUrl" maxlength="500" placeholder="Logo URL" class="rounded-2xl border border-violet-100 px-4 py-3 text-sm outline-none focus:border-violet-300 focus:ring-4 focus:ring-violet-100" />
          </div>
          <div class="grid gap-3 sm:grid-cols-[1fr_120px]">
            <input v-model="sponsorForm.tier" maxlength="80" placeholder="Tier" class="rounded-2xl border border-violet-100 px-4 py-3 text-sm outline-none focus:border-violet-300 focus:ring-4 focus:ring-violet-100" />
            <input v-model.number="sponsorForm.sortOrder" type="number" min="0" max="9999" class="rounded-2xl border border-violet-100 px-4 py-3 text-sm outline-none focus:border-violet-300 focus:ring-4 focus:ring-violet-100" />
          </div>
          <textarea v-model="sponsorForm.description" rows="3" maxlength="500" placeholder="Beschreibung" class="w-full rounded-2xl border border-violet-100 px-4 py-3 text-sm outline-none focus:border-violet-300 focus:ring-4 focus:ring-violet-100" />
          <label class="flex items-center gap-3 rounded-2xl border border-violet-100 bg-violet-50/50 px-4 py-3 text-sm font-semibold text-slate-700">
            <input v-model="sponsorForm.isVisible" type="checkbox" class="h-4 w-4 rounded border-violet-200 text-violet-600" />
            Public anzeigen
          </label>
          <div class="flex flex-wrap gap-2">
            <Button type="submit" class="gap-2" :disabled="saving || localSaving">
              <Save class="h-4 w-4" />
              {{ editingSponsorId ? 'Sponsor speichern' : 'Sponsor anlegen' }}
            </Button>
            <Button type="button" variant="ghost" :disabled="saving || localSaving" @click="resetSponsorForm">
              <Plus class="h-4 w-4" />
              Neu
            </Button>
          </div>
        </form>

        <div class="divide-y divide-violet-100 border-t border-violet-100">
          <article v-for="sponsor in store.adminSponsors" :key="sponsor.id" class="flex items-start justify-between gap-3 p-4">
            <div class="min-w-0">
              <p class="truncate text-sm font-bold text-slate-900">{{ sponsor.name }}</p>
              <p class="mt-1 text-xs font-semibold text-slate-500">{{ sponsor.tier }} · Reihenfolge {{ sponsor.sortOrder }}</p>
              <p class="mt-1 text-xs" :class="sponsor.isVisible ? 'text-emerald-700' : 'text-slate-500'">
                {{ sponsor.isVisible ? 'Public sichtbar' : 'Verborgen' }}
              </p>
            </div>
            <div class="flex shrink-0 gap-2">
              <Button type="button" size="sm" variant="ghost" @click="editSponsor(sponsor)">Bearbeiten</Button>
              <Button type="button" size="sm" variant="ghost" class="text-rose-700" :disabled="saving || localSaving" @click="deleteSponsor(sponsor)">
                <Trash2 class="h-4 w-4" />
              </Button>
            </div>
          </article>
        </div>
      </div>
    </template>
  </div>

  <AdminContentFooterPreviewModal
    :open="previewOpen"
    :title="previewTitle"
    url=""
    :content-html="previewHtml"
    @close="previewOpen = false"
  />

  <Modal
    :open="selectedShowact !== null"
    size="xl"
    :title="selectedShowact ? `${selectedShowact.artistName} · Showact-Details` : 'Showact-Details'"
    :subtitle="selectedShowact ? `${statusLabel(selectedShowact.status)} · Eingereicht am ${new Date(selectedShowact.createdAt).toLocaleString('de-DE')}` : undefined"
    @close="closeShowactDetails"
  >
    <div v-if="selectedShowact" class="space-y-6">
      <div class="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
        <div class="rounded-2xl border border-violet-100 bg-violet-50/50 px-4 py-3">
          <p class="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">Artist</p>
          <p class="mt-1 text-sm font-semibold text-slate-900">{{ selectedShowact.artistName }}</p>
        </div>
        <div class="rounded-2xl border border-violet-100 bg-violet-50/50 px-4 py-3">
          <p class="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">Status</p>
          <p class="mt-1 text-sm font-semibold text-slate-900">{{ statusLabel(selectedShowact.status) }}</p>
        </div>
        <div class="rounded-2xl border border-violet-100 bg-violet-50/50 px-4 py-3">
          <p class="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">E-Mail</p>
          <p class="mt-1 text-sm font-semibold text-slate-900">{{ selectedShowact.contactEmail || 'Nicht angegeben' }}</p>
        </div>
        <div class="rounded-2xl border border-violet-100 bg-violet-50/50 px-4 py-3">
          <p class="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">Discord</p>
          <p class="mt-1 text-sm font-semibold text-slate-900">{{ selectedShowact.contactDiscord || 'Nicht angegeben' }}</p>
        </div>
      </div>

      <div class="grid gap-3 md:grid-cols-2">
        <div
          v-for="detail in showactSubmissionDetails"
          :key="detail.key"
          class="rounded-2xl border border-violet-100 bg-white px-4 py-3"
        >
          <p class="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">{{ detail.label }}</p>
          <p class="mt-1 whitespace-pre-wrap break-words text-sm leading-6 text-slate-800">{{ detail.value }}</p>
        </div>
      </div>
    </div>
  </Modal>
</template>
