<template>
  <div class="space-y-3">
    <article
      v-for="group in groups"
      :key="group.name"
      class="overflow-hidden rounded-2xl border bg-white/90 shadow-[0_14px_36px_rgba(124,91,180,0.08)] transition"
      :class="selectedGroupName === group.name ? 'border-violet-200 ring-2 ring-violet-100' : 'border-violet-100'"
    >
      <button
        type="button"
        class="grid w-full gap-3 border-b border-violet-100 bg-violet-50/45 px-4 py-4 text-left lg:grid-cols-[minmax(0,1fr)_auto] lg:items-center"
        @click="toggleGroup(group.name); $emit('select-group', group.name)"
      >
        <div class="min-w-0">
          <div class="flex min-w-0 flex-wrap items-center gap-2">
            <span class="grid h-8 w-8 shrink-0 place-items-center rounded-xl bg-white text-violet-700 shadow-sm">
              <FolderTree class="h-4 w-4" />
            </span>
            <h2 class="truncate text-lg font-bold text-slate-900">{{ group.name }}</h2>
            <span class="rounded-full bg-white px-2.5 py-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-violet-700">
              {{ group.totalCategories }} Unterkategorien
            </span>
          </div>
          <p class="mt-2 text-sm leading-6 text-slate-500">
            {{ group.totalVotes.toLocaleString('de-DE') }} Votes · {{ group.votedCategories }} mit Votes · {{ group.readyCount }} bereit
          </p>
        </div>

        <div class="flex flex-wrap items-center gap-2 lg:justify-end">
          <span class="rounded-full bg-emerald-50 px-3 py-1 text-xs font-semibold text-emerald-700">
            {{ group.winnerSetCount }} Gewinner
          </span>
          <span v-if="group.problemCount > 0" class="rounded-full bg-amber-50 px-3 py-1 text-xs font-semibold text-amber-700">
            {{ group.problemCount }} prüfen
          </span>
          <span class="grid h-8 w-8 shrink-0 place-items-center rounded-xl border border-violet-100 bg-white text-violet-700">
            <ChevronDown class="h-4 w-4 transition" :class="isExpanded(group.name) ? 'rotate-180' : ''" />
          </span>
        </div>
      </button>

      <div v-if="isExpanded(group.name)" class="divide-y divide-violet-100 bg-white">
        <article
          v-for="row in group.categories"
          :key="row.categoryId"
          class="grid gap-4 px-4 py-4 transition hover:bg-violet-50/35 xl:grid-cols-[minmax(280px,1.1fr)_minmax(0,1fr)_auto] xl:items-center"
          :class="focusedCategoryId === row.categoryId ? 'bg-violet-50/55' : ''"
          @click="$emit('select-category', row.categoryId)"
        >
          <div class="min-w-0">
            <div class="flex min-w-0 flex-wrap items-center gap-2">
              <span class="grid h-10 w-10 shrink-0 place-items-center rounded-2xl bg-violet-100/80 text-violet-700">
                <GitBranch class="h-5 w-5" />
              </span>
              <div class="min-w-0">
                <p class="truncate text-lg font-bold text-slate-900">{{ row.categoryName }}</p>
                <div class="mt-1 flex flex-wrap items-center gap-2">
                  <span class="inline-flex rounded-full border border-violet-200 bg-violet-50 px-2.5 py-1 text-[11px] font-semibold text-violet-700">
                    {{ viewerRangeLabel(row.viewerRangeMin, row.viewerRangeMax) }}
                  </span>
                  <span class="inline-flex rounded-full border border-slate-200 bg-white px-2.5 py-1 text-[11px] font-semibold text-slate-500">
                    {{ row.candidateCount > 0 ? `${row.candidateCount} Kandidaten im Rennen` : 'Noch kein Kandidatenfeld' }}
                  </span>
                </div>
              </div>
            </div>
          </div>

          <div class="grid gap-3">
            <div class="min-w-0">
              <div class="flex flex-wrap items-center gap-2">
                <span class="rounded-full border px-3 py-1 text-[11px] font-bold uppercase tracking-[0.14em]" :class="row.statusTone">
                  {{ row.statusLabel }}
                </span>
                <span v-if="row.showTopVoteTieWarning" class="rounded-full bg-amber-50 px-3 py-1 text-xs font-semibold text-amber-700">
                  Tie
                </span>
                <span v-if="row.showMissingClipWarning" class="rounded-full bg-amber-50 px-3 py-1 text-xs font-semibold text-amber-700">
                  Clip fehlt
                </span>
                <span v-if="row.showOpenReviewWarning" class="rounded-full bg-amber-50 px-3 py-1 text-xs font-semibold text-amber-700">
                  {{ row.openReviewCount }} Reviews
                </span>
                <span v-if="row.showRuleConflictWarning" class="rounded-full bg-amber-50 px-3 py-1 text-xs font-semibold text-amber-700">
                  Regelkonflikt
                </span>
              </div>
              <p class="mt-2 text-sm leading-6 text-slate-500">
                {{ summaryText(row) }}
              </p>
            </div>

            <div class="grid gap-2 text-center sm:grid-cols-2">
              <div class="rounded-2xl border border-violet-100 bg-violet-50/40 px-3 py-3">
                <p class="text-[10px] font-semibold uppercase tracking-[0.12em] text-slate-500">Votes</p>
                <strong class="mt-1 block text-base text-slate-950">{{ row.voteCount.toLocaleString('de-DE') }}</strong>
              </div>
              <div class="rounded-2xl border border-violet-100 bg-violet-50/40 px-3 py-3">
                <p class="text-[10px] font-semibold uppercase tracking-[0.12em] text-slate-500">Kandidaten</p>
                <strong class="mt-1 block text-base text-slate-950">{{ row.candidateCount }}</strong>
              </div>
            </div>
          </div>

          <div class="flex flex-wrap items-center gap-2 xl:justify-end" @click.stop>
            <button
              type="button"
              class="inline-flex items-center gap-2 rounded-full border border-violet-200 bg-white px-3 py-2 text-sm font-semibold text-violet-700 transition hover:bg-violet-50"
              @click="$emit('open-leaderboard', row)"
            >
              <ListOrdered class="h-4 w-4" />
              Leaderboard
            </button>
            <RouterLink
              class="inline-flex items-center gap-2 rounded-full border border-violet-200 bg-white px-3 py-2 text-sm font-semibold text-violet-700 transition hover:bg-violet-50"
              :to="`/admin/winners?categoryId=${row.categoryId}`"
            >
              Gewinner
              <ArrowRight class="h-4 w-4" />
            </RouterLink>
          </div>
        </article>
      </div>
    </article>

    <div v-if="groups.length === 0" class="rounded-2xl border border-dashed border-violet-200 bg-violet-50/50 px-4 py-12 text-center text-sm text-slate-500">
      Keine Hauptkategorien passen zu diesem Filter.
    </div>
  </div>
</template>

<script setup lang="ts">
import { ArrowRight, ChevronDown, FolderTree, GitBranch, ListOrdered } from '@lucide/vue'
import { ref, watch } from 'vue'
import { RouterLink } from 'vue-router'

import type { AdminVotingGroupSummary, AdminVotingWorkspaceRow } from './useAdminVotingManager'

const props = defineProps<{
  groups: AdminVotingGroupSummary[]
  selectedGroupName: string | null
  focusedCategoryId: number | null
}>()

defineEmits<{
  'select-group': [groupName: string]
  'select-category': [categoryId: number]
  'open-leaderboard': [row: AdminVotingWorkspaceRow]
}>()

const expandedGroup = ref<string | null>(null)

watch(
  () => props.groups.map((group) => group.name),
  (groupNames) => {
    if (!expandedGroup.value || !groupNames.includes(expandedGroup.value)) {
      expandedGroup.value = groupNames[0] ?? null
    }
  },
  { immediate: true },
)

watch(
  () => props.selectedGroupName,
  (groupName) => {
    if (groupName) {
      expandedGroup.value = groupName
    }
  },
)

function isExpanded(groupName: string) {
  return expandedGroup.value === groupName
}

function toggleGroup(groupName: string) {
  expandedGroup.value = groupName
}

function viewerRangeLabel(min: number | null, max: number | null) {
  if (min === null && max === null) return 'Offene Einordnung'
  if (min !== null && max === null) return `Ab ${min} Viewer`
  if (min === null && max !== null) return `Bis ${max} Viewer`
  return `${min} bis ${max} Viewer`
}

function summaryText(row: AdminVotingWorkspaceRow) {
  if (row.topCandidate && row.voteCount > 0) {
    return `${row.topCandidate.displayName} liegt aktuell vorne mit ${row.topCandidate.votes.toLocaleString('de-DE')} Votes.`
  }

  if (row.candidateCount > 0) {
    return 'Die Unterkategorie ist vorbereitet, aber bisher wurden noch keine Votes abgegeben.'
  }

  return 'Diese Unterkategorie hat aktuell noch kein aufgebautes Kandidatenfeld.'
}
</script>
