<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue'

import HomeMissingVotesConfirm from './HomeMissingVotesConfirm.vue'
import HomeWizardFooter from './HomeWizardFooter.vue'
import type { HomeCategoryListItem, HomeNomineeListItem } from './homeModalTypes'

const props = defineProps<{
  catList: HomeCategoryListItem[]
  activeCatIndex: number
  activeCatName: string
  noms: HomeNomineeListItem[]
  voteCount: number
  totalCats: number
  canSubmitVote: boolean
  savedVoteActive: boolean
  submitVote: () => Promise<void> | void
  submitting: boolean
  readonlyMode?: boolean
}>()

const confirmMissingVotes = ref(false)
const railRef = ref<HTMLElement | null>(null)
const contentRef = ref<HTMLElement | null>(null)
const activeCategoryRef = ref<HTMLElement | null>(null)
const activeCategoryItem = computed(() => props.catList[props.activeCatIndex] ?? null)
const missingVoteCategoryNames = computed(() => props.catList.filter((category) => !category.done).map((category) => category.displayName))
const submitLabel = computed(() => props.savedVoteActive ? 'Änderungen speichern' : 'Stimmen absenden')
const isLastCategory = computed(() => props.activeCatIndex >= props.catList.length - 1)
const groupedCatList = computed(() => {
  const groups: Array<{
    name: string
    items: HomeCategoryListItem[]
    doneCount: number
    candidateCount: number
  }> = []
  for (const category of props.catList) {
    const groupName = category.groupName?.trim() || 'Weitere Kategorien'
    const current = groups.at(-1)
    if (current?.name === groupName) {
      current.items.push(category)
      current.doneCount += category.done ? 1 : 0
      current.candidateCount += category.candidateCount
    } else {
      groups.push({
        name: groupName,
        items: [category],
        doneCount: category.done ? 1 : 0,
        candidateCount: category.candidateCount,
      })
    }
  }
  return groups
})
const footerPrimaryLabel = computed(() => {
  if (!isLastCategory.value) return 'Weiter'
  if (!props.canSubmitVote) return 'Erst Favorit:in wählen'
  return 'Stimmen prüfen'
})
const footerHelperText = computed(() =>
  confirmMissingVotes.value
    ? 'Prüfe die offenen Kategorien oder speichere deine aktuelle Auswahl.'
    : props.readonlyMode
      ? 'Hier siehst du die freigegebenen Kandidat:innen der abgeschlossenen Nominierungsphase.'
    : props.savedVoteActive
      ? 'Du bearbeitest dein gespeichertes Voting. Speichern ersetzt deine bisherige Auswahl.'
      : 'Du kannst Kategorien überspringen und vor dem Speichern prüfen.',
)
const footerActions = computed(() =>
  props.readonlyMode
    ? [
        {
          label: 'Zurück',
          tone: 'secondary' as const,
          disabled: props.activeCatIndex === 0,
          onClick: () => props.catList[Math.max(0, props.activeCatIndex - 1)]?.onClick(),
        },
        {
          label: 'Weiter',
          disabled: props.activeCatIndex >= props.catList.length - 1,
          onClick: () => props.catList[Math.min(props.catList.length - 1, props.activeCatIndex + 1)]?.onClick(),
        },
      ]
    :
  confirmMissingVotes.value
    ? [
        { label: 'Zurück zum Voting', tone: 'secondary' as const, disabled: props.submitting, onClick: hideMissingVoteConfirm },
        { label: props.submitting ? 'Speichert ...' : submitLabel.value, disabled: props.submitting, onClick: submitConfirmedVote },
      ]
    : [
        {
          label: 'Zurück',
          tone: 'secondary' as const,
          disabled: props.activeCatIndex === 0,
          onClick: () => props.catList[Math.max(0, props.activeCatIndex - 1)]?.onClick(),
        },
        {
          label: props.submitting ? 'Speichert ...' : footerPrimaryLabel.value,
          disabled: props.submitting || (isLastCategory.value && !props.canSubmitVote),
          onClick: goToNextCategory,
        },
      ],
)

function hideMissingVoteConfirm() {
  confirmMissingVotes.value = false
}

watch(
  () => props.activeCatIndex,
  async () => {
    confirmMissingVotes.value = false
    await nextTick()
    contentRef.value?.scrollTo({ top: 0 })
    syncActiveCategoryIntoRail()
  },
)

function setCategoryButtonRef(element: unknown, categoryIndex: number) {
  if (categoryIndex === props.activeCatIndex) {
    activeCategoryRef.value = element instanceof HTMLElement ? element : null
  }
}

function syncActiveCategoryIntoRail() {
  const rail = railRef.value
  const activeButton = activeCategoryRef.value
  if (!rail || !activeButton) return

  const isHorizontalRail = rail.scrollWidth > rail.clientWidth && rail.clientWidth >= rail.clientHeight
  if (isHorizontalRail) {
    const buttonCenter = activeButton.offsetLeft + activeButton.offsetWidth / 2
    const targetLeft = Math.max(0, buttonCenter - rail.clientWidth / 2)
    rail.scrollTo({ left: targetLeft })
    return
  }

  const targetTop = Math.max(0, activeButton.offsetTop - Math.max(12, (rail.clientHeight - activeButton.offsetHeight) / 2))
  rail.scrollTo({ top: targetTop })
}

function goToNextCategory() {
  if (isLastCategory.value) {
    if (!props.canSubmitVote) return
    confirmMissingVotes.value = missingVoteCategoryNames.value.length > 0
    if (!confirmMissingVotes.value) {
      void props.submitVote()
    }
    return
  }

  props.catList[props.activeCatIndex + 1]?.onClick()
}

async function submitConfirmedVote() {
  await props.submitVote()
}
</script>

<template>
  <div class="home-vote-picker">
    <aside ref="railRef" class="home-vote-picker__rail">
      <div class="home-vote-picker__rail-label">Hauptkategorien</div>
      <section v-for="group in groupedCatList" :key="group.name" class="home-vote-picker__rail-group">
        <div class="home-vote-picker__rail-group-label">{{ group.name }}</div>
        <button
          v-for="cat in group.items"
          :key="cat.idx"
          :ref="(element) => setCategoryButtonRef(element, cat.idx)"
          type="button"
          class="home-vote-picker__category-button"
          :aria-current="cat.idx === props.activeCatIndex ? 'true' : undefined"
          @click="cat.onClick"
          @pointerdown.prevent
          :style="cat.rowStyle"
        >
          <span :style="cat.iconStyle">{{ cat.icon }}</span>
          <span class="home-vote-picker__category-copy">
            <span class="home-vote-picker__category-tier">{{ cat.name }}</span>
          </span>
          <span v-if="!props.readonlyMode" :style="cat.checkStyle">✓</span>
        </button>
      </section>
    </aside>

    <section ref="contentRef" class="home-vote-picker__content">
      <HomeMissingVotesConfirm
        v-if="confirmMissingVotes"
        :missing-categories="missingVoteCategoryNames"
        :on-back="hideMissingVoteConfirm"
        :on-confirm="submitConfirmedVote"
        :submitting="props.submitting"
        :submit-label="submitLabel"
        hide-actions
      />
      <template v-else>
      <header class="home-vote-picker__category-header">
        <div>
          <p v-if="activeCategoryItem?.groupName" class="home-vote-picker__eyebrow">{{ activeCategoryItem.groupName }}</p>
          <h4>{{ activeCategoryItem?.name || props.activeCatName }}</h4>
        </div>
      </header>

      <p v-if="props.savedVoteActive && !props.readonlyMode" class="home-vote-picker__edit-banner">
        Du bearbeitest dein gespeichertes Voting. Speichern ersetzt deine bisherige Auswahl.
      </p>

      <div class="home-vote-picker__cards">
        <template v-for="(nom, __idx) in props.noms" :key="nom.idx ?? __idx">
          <a
            v-if="props.readonlyMode && nom.url"
            class="home-nomination-summary-card home-nomination-summary-card--clickable"
            :href="nom.url"
            target="_blank"
            rel="noopener noreferrer"
            referrerpolicy="no-referrer"
          >
            <div class="home-nomination-summary-card__avatar">{{ nom.initials || '✦' }}</div>
            <div class="home-nomination-summary-card__body">
              <h5>{{ nom.name }}</h5>
              <span>{{ nom.handle || nom.platform }}</span>
            </div>
          </a>
          <article v-else-if="props.readonlyMode" class="home-nomination-summary-card">
            <div class="home-nomination-summary-card__avatar">{{ nom.initials || '✦' }}</div>
            <div class="home-nomination-summary-card__body">
              <h5>{{ nom.name }}</h5>
              <span>{{ nom.handle || nom.platform }}</span>
            </div>
          </article>
          <article v-else class="home-vote-card" :class="{ 'home-vote-card--selected': nom.selected, 'home-vote-card--missing-clip': !nom.hasClip }">
            <div v-if="nom.selected" class="home-vote-card__burst" aria-hidden="true">
              <span class="home-vote-card__sky-glow"></span>
              <span class="home-vote-card__sky-sweep"></span>
              <span class="home-vote-card__sky-star home-vote-card__sky-star--one">✦</span>
              <span class="home-vote-card__sky-star home-vote-card__sky-star--two">✧</span>
              <span class="home-vote-card__sky-star home-vote-card__sky-star--three">★</span>
              <span class="home-vote-card__sky-star home-vote-card__sky-star--four">✦</span>
              <span class="home-vote-card__sky-star home-vote-card__sky-star--five">✧</span>
              <span class="home-vote-card__sky-star home-vote-card__sky-star--six">✦</span>
              <span class="home-vote-card__sky-star home-vote-card__sky-star--seven">✧</span>
              <span class="home-vote-card__sky-star home-vote-card__sky-star--eight">★</span>
              <span class="home-vote-card__sky-star home-vote-card__sky-star--nine">✦</span>
              <span class="home-vote-card__sky-star home-vote-card__sky-star--ten">✧</span>
            </div>
            <div class="home-vote-card__top">
              <div class="home-vote-card__identity">
                <div class="home-vote-card__avatar">{{ nom.initials || '✦' }}</div>
                <div class="home-vote-card__name-block">
                  <div class="home-vote-card__name-row">
                    <h5>{{ nom.name }}</h5>
                    <span>{{ nom.platform }}</span>
                  </div>
                  <p>{{ nom.handle }}</p>
                </div>
              </div>

              <template v-if="nom.showPick">
                <button class="home-vote-card__pick" :class="{ 'home-vote-card__pick--selected': nom.selected }" @click="nom.onPick">
                  {{ nom.btnLabel }}
                </button>
              </template>
            </div>

            <div class="home-vote-card__clip" @click.stop>
              <div class="home-vote-card__clip-header">
                <span class="home-vote-card__clip-platform">{{ nom.clipPlatform }}</span>
                <a
                  v-if="nom.clipUrl"
                  :href="nom.clipUrl"
                  target="_blank"
                  rel="noopener noreferrer"
                  referrerpolicy="no-referrer"
                >
                  {{ nom.clipTitle }}
                </a>
                <span v-else>Kein geprüfter Clip für diese Kategorie hinterlegt.</span>
              </div>

              <iframe
                v-if="nom.clipEmbedUrl"
                class="home-vote-card__clip-player"
                :src="nom.clipEmbedUrl"
                :title="nom.clipEmbedTitle"
                loading="lazy"
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture; web-share"
                allowfullscreen
                referrerpolicy="strict-origin-when-cross-origin"
              />

              <p v-else-if="nom.clipUrl" class="home-vote-card__clip-fallback">
                Dieser Clip kann nicht eingebettet werden, ist aber über den Link erreichbar.
              </p>
            </div>

          </article>
        </template>

        <div v-if="props.noms.length === 0" class="home-vote-picker__empty">
          Für diese Kategorie sind noch keine Kandidat:innen freigegeben.
        </div>
      </div>
      </template>
    </section>
  </div>

  <HomeWizardFooter
    :progress-text="props.readonlyMode ? `${props.totalCats} Kategorien` : `${props.voteCount} / ${props.totalCats} Kategorien gewählt`"
    :helper-text="footerHelperText"
    :actions="footerActions"
  />
</template>
