<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue'
import Select from 'primevue/select'
import { Search, Sparkles, Tags, UserPlus, Users } from '@lucide/vue'

import AdminPageHeader from '../../components/admin/AdminPageHeader.vue'
import AdminSeasonToolbar from '../../components/admin/AdminSeasonToolbar.vue'
import Button from '../../components/ui/Button.vue'
import Card from '../../components/ui/Card.vue'
import { useAwardsStore } from '../../stores/awards'

const store = useAwardsStore()
const candidateSaving = ref<number | 'new' | null>(null)
const adminMessage = ref('')
const adminError = ref('')

const newCandidateForm = reactive({
  categoryId: 0,
  displayName: '',
  channelSlug: '',
  platform: 'Twitch',
})

const candidateForms = reactive<Record<number, {
  categoryId: number
  displayName: string
  channelSlug: string
  platform: string
}>>({})

const seasonDetail = computed(() => store.adminSeasonDetail)
const selectedSeasonId = computed(() => store.adminSelectedSeasonId)
const candidateFilter = ref('')
const categoryFilter = ref<number | null>(null)
const categoryOptions = computed(() =>
  seasonDetail.value.categories.map((category) => ({
    label: `${category.groupName} · ${category.name}`,
    value: category.id,
  })),
)
const categoryFilterOptions = computed(() => [
  { label: 'Alle Kategorien', value: null },
  ...categoryOptions.value,
])
const categoryLabelMap = computed(() =>
  Object.fromEntries(seasonDetail.value.categories.map((category) => [category.id, `${category.groupName} · ${category.name}`])),
)
const platformSummary = computed(() => {
  const platforms = new Set(seasonDetail.value.candidates.map((candidate) => candidate.platform).filter(Boolean))
  return platforms.size
})
const candidateStats = computed(() => [
  { label: 'Kandidaten', value: seasonDetail.value.candidates.length, note: 'im Jahr gepflegt' },
  { label: 'Kategorien', value: seasonDetail.value.categories.length, note: 'als Ziel verfuegbar' },
  { label: 'Plattformen', value: platformSummary.value, note: 'in der Kandidatenbasis' },
])
const filteredCandidates = computed(() => {
  const query = candidateFilter.value.trim().toLowerCase()
  const candidates = categoryFilter.value
    ? seasonDetail.value.candidates.filter((candidate) => candidate.categoryId === categoryFilter.value)
    : seasonDetail.value.candidates

  if (!query) return candidates
  return candidates.filter((candidate) =>
    [candidate.displayName, candidate.channelSlug, candidate.platform, categoryLabelMap.value[candidate.categoryId] ?? '']
      .join(' ')
      .toLowerCase()
      .includes(query),
  )
})
const hasFilters = computed(() => candidateFilter.value.trim().length > 0 || categoryFilter.value !== null)
const canCreateCandidate = computed(() =>
  Boolean(selectedSeasonId.value && newCandidateForm.categoryId && newCandidateForm.displayName.trim() && newCandidateForm.channelSlug.trim()),
)

watch(
  seasonDetail,
  (detail) => {
    for (const candidate of detail.candidates) {
      candidateForms[candidate.id] = {
        categoryId: candidate.categoryId,
        displayName: candidate.displayName,
        channelSlug: candidate.channelSlug,
        platform: candidate.platform,
      }
    }

    newCandidateForm.categoryId = detail.categories[0]?.id ?? 0
  },
  { immediate: true },
)

async function saveCandidate(candidateId: number) {
  if (!selectedSeasonId.value) return

  candidateSaving.value = candidateId
  adminMessage.value = ''
  adminError.value = ''

  try {
    await store.updateAdminCandidate(candidateId, selectedSeasonId.value, candidateForms[candidateId])
    adminMessage.value = 'Kandidat gespeichert.'
  } catch (error) {
    adminError.value = error instanceof Error ? error.message : 'Kandidat konnte nicht gespeichert werden.'
  } finally {
    candidateSaving.value = null
  }
}

async function createCandidate() {
  if (!canCreateCandidate.value || !selectedSeasonId.value) return

  candidateSaving.value = 'new'
  adminMessage.value = ''
  adminError.value = ''

  try {
    await store.createAdminCandidate(selectedSeasonId.value, newCandidateForm)
    adminMessage.value = 'Kandidat angelegt.'
    newCandidateForm.displayName = ''
    newCandidateForm.channelSlug = ''
    newCandidateForm.platform = 'Twitch'
  } catch (error) {
    adminError.value = error instanceof Error ? error.message : 'Kandidat konnte nicht angelegt werden.'
  } finally {
    candidateSaving.value = null
  }
}

function clearFilters() {
  candidateFilter.value = ''
  categoryFilter.value = null
}
</script>

<template>
  <div class="space-y-6">
    <AdminPageHeader
      eyebrow="Kandidaten"
      title="Kandidatenbasis pflegen"
      description="Schneller finden, sauber pruefen, gezielt bearbeiten: die Kandidaten sind jetzt nach Jahr, Kategorie und Handle besser steuerbar."
    />

    <AdminSeasonToolbar />

    <div class="grid gap-4 md:grid-cols-3">
      <Card
        v-for="stat in candidateStats"
        :key="stat.label"
        class="p-5"
      >
        <p class="text-[11px] font-semibold uppercase tracking-[0.24em] text-violet-500">{{ stat.label }}</p>
        <strong class="mt-2 block text-3xl text-violet-800">{{ stat.value }}</strong>
        <p class="mt-1 text-sm text-slate-500">{{ stat.note }}</p>
      </Card>
    </div>

    <div class="grid gap-6 xl:grid-cols-[minmax(0,1fr)_360px]">
      <Card class="overflow-hidden">
        <div class="border-b border-violet-100 bg-white/70 p-6">
          <div class="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
            <div>
              <p class="text-xs font-semibold uppercase tracking-[0.26em] text-violet-500">Kandidatenbereich</p>
              <h2 class="mt-2 font-[Cormorant_Garamond] text-4xl text-violet-800">Suchen, pruefen, aktualisieren</h2>
              <p class="mt-2 max-w-2xl text-sm leading-6 text-slate-500">
                Filtere nach Kategorie oder Handle und bearbeite nur den Kandidaten, der wirklich geaendert werden muss.
              </p>
            </div>
            <div class="rounded-2xl border border-violet-100 bg-violet-50/60 px-4 py-3 text-sm text-slate-600">
              <strong class="text-violet-800">{{ filteredCandidates.length }}</strong> von {{ seasonDetail.candidates.length }} sichtbar
            </div>
          </div>

          <div class="mt-5 grid gap-3 lg:grid-cols-[minmax(0,1fr)_280px_auto]">
            <label class="relative block">
              <Search class="pointer-events-none absolute left-4 top-1/2 h-4 w-4 -translate-y-1/2 text-violet-400" />
              <input
                v-model="candidateFilter"
                type="text"
                class="h-12 w-full rounded-2xl border border-violet-200 bg-white/90 pl-11 pr-4 text-sm text-slate-700 outline-none transition focus:border-violet-400 focus:ring-4 focus:ring-violet-100"
                placeholder="Name, Handle, Plattform oder Kategorie suchen"
              />
            </label>
            <Select
              v-model="categoryFilter"
              :options="categoryFilterOptions"
              option-label="label"
              option-value="value"
              class="w-full"
            />
            <Button v-if="hasFilters" variant="ghost" @click="clearFilters">Filter loeschen</Button>
          </div>
        </div>

        <div class="p-5">
          <div class="grid gap-4">
            <article
              v-for="candidate in filteredCandidates"
              :key="candidate.id"
              class="rounded-[26px] border border-violet-100 bg-white/90 p-5 shadow-[0_16px_42px_rgba(168,145,214,0.08)]"
            >
              <div class="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
                <div class="min-w-0">
                  <div class="flex flex-wrap items-center gap-2">
                    <span class="rounded-full border border-amber-200 bg-amber-50 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-amber-700">
                      {{ candidate.platform }}
                    </span>
                    <span class="rounded-full border border-violet-100 bg-violet-50/70 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-violet-700">
                      {{ categoryLabelMap[candidate.categoryId] || 'Ohne Kategorie' }}
                    </span>
                  </div>
                  <h3 class="mt-3 truncate font-[Cormorant_Garamond] text-4xl text-violet-800">{{ candidate.displayName }}</h3>
                  <p class="mt-1 text-sm font-semibold text-slate-500">{{ candidate.channelSlug }}</p>
                </div>
                <Button :disabled="candidateSaving === candidate.id" size="sm" @click="saveCandidate(candidate.id)">
                  {{ candidateSaving === candidate.id ? 'Speichert ...' : 'Speichern' }}
                </Button>
              </div>

              <div class="mt-5 grid gap-3 md:grid-cols-2">
                <label class="space-y-2">
                  <span class="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Kategorie</span>
                  <Select
                    v-model="candidateForms[candidate.id].categoryId"
                    :options="categoryOptions"
                    option-label="label"
                    option-value="value"
                    class="w-full"
                  />
                </label>
                <label class="space-y-2">
                  <span class="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Anzeigename</span>
                  <input v-model="candidateForms[candidate.id].displayName" type="text" class="h-12 w-full rounded-2xl border border-violet-200 bg-white px-4 text-sm outline-none transition focus:border-violet-400 focus:ring-4 focus:ring-violet-100" placeholder="Anzeigename" />
                </label>
                <label class="space-y-2">
                  <span class="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Handle</span>
                  <input v-model="candidateForms[candidate.id].channelSlug" type="text" class="h-12 w-full rounded-2xl border border-violet-200 bg-white px-4 text-sm outline-none transition focus:border-violet-400 focus:ring-4 focus:ring-violet-100" placeholder="@channel" />
                </label>
                <label class="space-y-2">
                  <span class="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Plattform</span>
                  <input v-model="candidateForms[candidate.id].platform" type="text" class="h-12 w-full rounded-2xl border border-violet-200 bg-white px-4 text-sm outline-none transition focus:border-violet-400 focus:ring-4 focus:ring-violet-100" placeholder="Twitch, YouTube, ..." />
                </label>
              </div>
            </article>

            <p v-if="filteredCandidates.length === 0" class="rounded-[26px] border border-dashed border-violet-100 px-5 py-6 text-sm text-slate-500">
              Keine Kandidaten passen zum aktuellen Filter.
            </p>
          </div>
        </div>
      </Card>

      <aside class="space-y-4 xl:sticky xl:top-6 xl:self-start">
        <Card class="p-6">
          <div class="flex items-start gap-4">
            <div class="rounded-2xl bg-violet-100 p-3 text-violet-700">
              <UserPlus class="h-5 w-5" />
            </div>
            <div>
              <p class="text-xs font-semibold uppercase tracking-[0.24em] text-violet-500">Neu</p>
              <h2 class="mt-1 font-[Cormorant_Garamond] text-4xl text-violet-800">Kandidat anlegen</h2>
              <p class="mt-1 text-sm leading-6 text-slate-500">Erstelle bekannte Kandidaten direkt fuer die richtige Kategorie.</p>
            </div>
          </div>

          <div class="mt-6 space-y-4">
            <label class="space-y-2">
              <span class="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Kategorie</span>
              <Select
                v-model="newCandidateForm.categoryId"
                :options="categoryOptions"
                option-label="label"
                option-value="value"
                class="w-full"
              />
            </label>
            <label class="space-y-2">
              <span class="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Anzeigename</span>
              <input v-model="newCandidateForm.displayName" type="text" class="h-12 w-full rounded-2xl border border-violet-200 px-4 text-sm outline-none transition focus:border-violet-400 focus:ring-4 focus:ring-violet-100" placeholder="z.B. Jayuhime" />
            </label>
            <label class="space-y-2">
              <span class="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Handle</span>
              <input v-model="newCandidateForm.channelSlug" type="text" class="h-12 w-full rounded-2xl border border-violet-200 px-4 text-sm outline-none transition focus:border-violet-400 focus:ring-4 focus:ring-violet-100" placeholder="@channel" />
            </label>
            <label class="space-y-2">
              <span class="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Plattform</span>
              <input v-model="newCandidateForm.platform" type="text" class="h-12 w-full rounded-2xl border border-violet-200 px-4 text-sm outline-none transition focus:border-violet-400 focus:ring-4 focus:ring-violet-100" placeholder="Twitch" />
            </label>
            <Button class="w-full" :disabled="candidateSaving === 'new' || !canCreateCandidate" @click="createCandidate">
              {{ candidateSaving === 'new' ? 'Erstellt ...' : 'Kandidat anlegen' }}
            </Button>
          </div>

          <p v-if="adminMessage" class="mt-6 rounded-2xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-700">
            {{ adminMessage }}
          </p>
          <p v-if="adminError" class="mt-6 rounded-2xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">
            {{ adminError }}
          </p>
        </Card>

        <Card class="p-5">
          <div class="flex items-center gap-3">
            <Sparkles class="h-5 w-5 text-amber-500" />
            <p class="text-xs font-semibold uppercase tracking-[0.24em] text-violet-500">Ablauf</p>
          </div>
          <div class="mt-4 space-y-3 text-sm leading-6 text-slate-600">
            <p class="flex gap-3"><Users class="mt-0.5 h-4 w-4 shrink-0 text-violet-500" /> Erst Kandidaten suchen, damit du keine Duplikate anlegst.</p>
            <p class="flex gap-3"><Tags class="mt-0.5 h-4 w-4 shrink-0 text-violet-500" /> Kategorie-Chip pruefen, dann nur die noetigen Felder anpassen.</p>
          </div>
        </Card>
      </aside>
    </div>
  </div>
</template>
