<script setup lang="ts">
// <!-- ld-v2 --> Élection — désignation par avatar parmi la liste arrêtée,
// vote blanc (participation, pas désignation), règle affichée en une phrase.
// Égalité : l'outil ne départage JAMAIS — session de départage chaînée.
import { useCollectiveStore } from '~/stores/collective'
import { useDecisionsStore } from '~/stores/decisions'
import { BLANK_VOTE, ELECTION_RULE } from '~/lexicon'
import type { Decision, Id, Person, Protocol, VoteSession } from '~/types/domain'

const props = defineProps<{
  decision: Decision
  session: VoteSession
  protocol: Protocol
  secret?: boolean
  canAct?: boolean
  asPersonId?: Id
}>()

const col = useCollectiveStore()
const store = useDecisionsStore()

const eligible = computed<Person[]>(() =>
  col.people.filter(p => props.session.corpusPersonIds.includes(p.id)))
const active = computed(() => store.activeVotes(props.session.id))

const counts = computed(() => {
  const tallyMap: Record<Id, number> = {}
  for (const vote of active.value) {
    if (vote.choicePersonId) tallyMap[vote.choicePersonId] = (tallyMap[vote.choicePersonId] ?? 0) + 1
  }
  return tallyMap
})
const blanks = computed(() => active.value.filter(v => !v.choicePersonId).length)

const voterId = computed(() => props.asPersonId ?? col.me?.id)
const myVote = computed(() => active.value.find(v => v.voterId === voterId.value))
const selected = ref<Id | null>(null)
const error = ref('')

function cast(choicePersonId?: Id) {
  error.value = ''
  const result = store.castVote(props.session.id, {
    ...(choicePersonId !== undefined ? { choicePersonId } : {}),
    ...(props.asPersonId ? { asPersonId: props.asPersonId } : {}),
  })
  if ('ok' in result) error.value = result.reason
  else selected.value = null
}

const result = computed(() => {
  if (props.session.status !== 'closed') return null
  const tallied = store.tally(props.session)
  return !('ok' in tallied) && tallied.method === 'election' ? tallied.result : null
})
function name(id: Id): string {
  return col.people.find(p => p.id === id)?.displayName ?? '—'
}
function initials(personName: string): string {
  return personName.split(/[\s-]+/).map(w => w[0] ?? '').join('').slice(0, 2).toUpperCase()
}
function tint(id: string): string {
  let h = 0
  for (let i = 0; i < id.length; i++) h = (h * 31 + id.charCodeAt(i)) % 360
  return `oklch(0.72 0.09 ${h})`
}
function openRunoff() {
  navigateTo({
    path: '/decider',
    query: {
      parent: props.decision.id,
      chain: 'revision',
      title: `Départager — ${props.decision.title}`,
    },
  })
}
const drawPlanned = computed(() => props.protocol.formula.tieBreak === 'draw')
</script>

<template>
  <!-- ld-v2 -->
  <section class="ld-card ve">
    <p class="ve__rule">
      <UIcon name="i-lucide-scale" />
      <span>{{ ELECTION_RULE }}</span>
    </p>

    <!-- La grille de désignation -->
    <div class="ve__grid" role="radiogroup" aria-label="Désigner une personne">
      <button
        v-for="person in eligible"
        :key="person.id"
        type="button"
        class="ve__tile"
        :class="{
          've__tile--picked': selected === person.id,
          've__tile--mine': myVote?.choicePersonId === person.id,
          've__tile--winner': result?.outcome === 'elected' && result.winnerId === person.id,
        }"
        :disabled="!canAct || session.status !== 'open'"
        @click="selected = selected === person.id ? null : person.id"
      >
        <span class="ve__avatar" :style="{ background: tint(person.id) }">{{ initials(person.displayName) }}</span>
        <span class="ve__name">{{ person.displayName }}</span>
        <span v-if="(counts[person.id] ?? 0) > 0" class="ve__count">{{ counts[person.id] }}</span>
      </button>
    </div>

    <div v-if="session.status === 'open'" class="ve__actions">
      <button class="ld-btn" type="button" :disabled="!canAct || !selected" @click="cast(selected ?? undefined)">
        {{ selected ? `Désigner ${name(selected)}` : 'Désigner' }}
      </button>
      <button class="ld-btn ld-btn--ghost" type="button" :disabled="!canAct" @click="cast()">
        {{ BLANK_VOTE }}
      </button>
      <span v-if="myVote" class="ve__mine">
        Ton geste actuel : {{ myVote.choicePersonId ? name(myVote.choicePersonId) : BLANK_VOTE.toLowerCase() }}
      </span>
    </div>
    <p v-if="error" class="ve__error">{{ error }}</p>

    <p class="ve__tally">
      {{ active.length }} participant{{ active.length > 1 ? 's' : '' }}
      · {{ blanks }} vote{{ blanks > 1 ? 's' : '' }} blanc{{ blanks > 1 ? 's' : '' }}
      <template v-if="protocol.formula.electionMinParticipants !== undefined">
        · quorum : {{ protocol.formula.electionMinParticipants }}
      </template>
    </p>

    <!-- Clôture -->
    <div v-if="result" class="ve__result">
      <p v-if="result.outcome === 'elected'" class="ve__elected">
        <UIcon name="i-lucide-award" />
        <span><strong>{{ name(result.winnerId) }}</strong> est désigné·e à la pluralité simple.</span>
      </p>
      <template v-else-if="result.outcome === 'tie'">
        <p class="ve__tie">
          Égalité entre {{ result.exAequoIds.map(name).join(' et ') }} —
          {{ drawPlanned ? 'le Pacte prévoit un tirage au sort entre ex æquo.' : 'à vous de départager.' }}
        </p>
        <button class="ld-btn" type="button" @click="openRunoff()">
          Ouvrir la session de départage
        </button>
      </template>
      <p v-else class="ve__rejected">
        <template v-if="result.reason === 'quorum'">
          {{ result.participants }} participant{{ result.participants > 1 ? 's' : '' }} sur
          {{ result.required }} requis — le quorum n'est pas atteint.
        </template>
        <template v-else>
          Personne n'a été désigné·e — tous les votes sont blancs.
        </template>
      </p>
    </div>
  </section>
</template>

<style scoped>
.ve { padding: 1.25rem; display: flex; flex-direction: column; gap: 0.9rem; }
.ve__rule {
  display: flex; align-items: baseline; gap: 0.45rem; margin: 0;
  font-size: 0.875rem; color: var(--mood-text-muted); line-height: 1.5;
}
.ve__grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr)); gap: 0.6rem;
}
.ve__tile {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 0.4rem;
  padding: 0.8rem 0.5rem; border-radius: var(--r-icon); cursor: pointer;
  background: var(--mood-bg); transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.ve__tile:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 3px 10px var(--mood-shadow); }
.ve__tile:disabled { cursor: default; }
.ve__tile--picked { box-shadow: 0 0 0 2.5px var(--mood-accent); background: var(--mood-accent-soft); }
.ve__tile--mine:not(.ve__tile--picked) { box-shadow: inset 0 0 0 2px var(--mood-accent); }
.ve__tile--winner { background: var(--mood-status-vigueur-bg); box-shadow: 0 0 0 2.5px var(--mood-status-vigueur); }
.ve__avatar {
  width: 2.75rem; height: 2.75rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 0.9375rem; color: rgba(255, 255, 255, 0.95);
}
.ve__name { font-size: 0.8125rem; font-weight: 600; text-align: center; line-height: 1.2; }
.ve__count {
  position: absolute; top: 0.4rem; right: 0.4rem;
  min-width: 1.35rem; height: 1.35rem; padding: 0 0.3rem;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-pill); font-size: 0.75rem; font-weight: 800;
  background: var(--mood-accent); color: var(--mood-accent-text);
}
.ve__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.ve__mine { font-size: 0.8125rem; color: var(--mood-text-muted); }
.ve__error { margin: 0; font-size: 0.875rem; font-weight: 600; color: var(--mood-error); }
.ve__tally { margin: 0; font-size: 0.8125rem; color: var(--mood-text-muted); }
.ve__result { display: flex; flex-direction: column; gap: 0.6rem; }
.ve__elected { display: flex; align-items: baseline; gap: 0.45rem; margin: 0; font-size: 1rem; color: var(--mood-status-vigueur); }
.ve__tie { margin: 0; font-weight: 600; font-size: 0.9375rem; color: var(--mood-warning); }
.ve__result .ld-btn { align-self: flex-start; }
.ve__rejected { margin: 0; font-weight: 600; font-size: 0.9375rem; color: var(--mood-text-muted); }
</style>
