<script setup lang="ts">
// <!-- ld-v2 --> Consentement — « Ça me va » est un geste stocké (Assent),
// l'objection s'argumente toujours. Zéro objection maintenue = adopté.
import { useCollectiveStore } from '~/stores/collective'
import { useDecisionsStore } from '~/stores/decisions'
import { WINDOW_OBJECT, WINDOW_OK } from '~/lexicon'
import type { Decision, Id, VoteSession } from '~/types/domain'

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

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

const assents = computed(() => col.assents.filter(a => a.decisionId === props.decision.id))
const objections = computed(() => col.objections.filter(o => o.decisionId === props.decision.id))
const openObjections = computed(() => objections.value.filter(o => o.status === 'open'))
const liftedObjections = computed(() => objections.value.filter(o => o.status !== 'open'))
const assentPeople = computed(() =>
  assents.value
    .map(a => col.people.find(p => p.id === a.personId))
    .filter((p): p is NonNullable<typeof p> => p !== undefined)
    .map(person => ({ person })),
)

const gaveAssent = computed(() => {
  const id = props.asPersonId ?? col.me?.id
  return assents.value.some(a => a.personId === id)
})

const objecting = ref(false)
const argument = ref('')
const error = ref('')

function name(id: Id): string {
  return col.people.find(p => p.id === id)?.displayName ?? '—'
}
function assent() {
  error.value = ''
  const result = store.assentTo(props.decision.id, props.asPersonId)
  if ('ok' in result) error.value = result.reason
}
function object() {
  error.value = ''
  const result = store.objectTo(props.decision.id, 'content', argument.value, props.asPersonId)
  if ('ok' in result) { error.value = result.reason; return }
  argument.value = ''
  objecting.value = false
}

const STATUS_LABEL = { withdrawn: 'levée', integrated: 'intégrée', escalated: 'escaladée' } as const
</script>

<template>
  <!-- ld-v2 -->
  <section class="ld-card vc">
    <!-- Les deux gestes -->
    <div v-if="session.status === 'open'" class="vc__gestures">
      <button class="vc__ok" type="button" :disabled="!canAct || gaveAssent" @click="assent()">
        <UIcon name="i-lucide-check" class="vc__gesture-icon" />
        <span>{{ WINDOW_OK }}</span>
        <span v-if="gaveAssent" class="vc__done">c'est noté</span>
      </button>
      <button class="vc__no" type="button" :disabled="!canAct" @click="objecting = !objecting">
        <UIcon name="i-lucide-hand" class="vc__gesture-icon" />
        <span>{{ WINDOW_OBJECT }}</span>
      </button>
    </div>
    <div v-if="objecting && session.status === 'open'" class="vc__argue">
      <textarea
        v-model="argument"
        rows="3"
        placeholder="Une objection s'argumente — écris pourquoi."
      />
      <button class="ld-btn" type="button" :disabled="!argument.trim()" @click="object()">
        Déposer l'objection
      </button>
    </div>
    <p v-if="error" class="vc__error">{{ error }}</p>

    <!-- Décomptes agrégés -->
    <div class="vc__tally">
      <span class="vc__count">
        <strong>{{ assents.length }}</strong>
        {{ assents.length > 1 ? 'accords' : 'accord' }}
      </span>
      <LdAvatarStack v-if="!secret && assentPeople.length" :people="assentPeople" :size="26" />
      <span class="vc__count">
        <strong>{{ openObjections.length }}</strong>
        {{ openObjections.length > 1 ? 'objections ouvertes' : 'objection ouverte' }}
      </span>
    </div>

    <!-- Objections ouvertes puis levées -->
    <ul v-if="objections.length" class="vc__objections">
      <li v-for="objection in openObjections" :key="objection.id" class="vc__objection vc__objection--open">
        <span class="vc__objection-state">ouverte</span>
        <span v-if="!secret" class="vc__objection-who">{{ name(objection.personId) }}</span>
        <p>{{ objection.argument }}</p>
      </li>
      <li v-for="objection in liftedObjections" :key="objection.id" class="vc__objection">
        <span class="vc__objection-state vc__objection-state--lifted">
          {{ STATUS_LABEL[objection.status as keyof typeof STATUS_LABEL] ?? objection.status }}
        </span>
        <span v-if="!secret" class="vc__objection-who">{{ name(objection.personId) }}</span>
        <p>{{ objection.argument }}</p>
        <p v-if="objection.resolutionNote" class="vc__resolution">{{ objection.resolutionNote }}</p>
      </li>
    </ul>

    <!-- Clôture -->
    <p v-if="session.status === 'closed'" class="vc__outcome">
      <template v-if="session.outcome === 'adopted'">
        Aucune objection maintenue à l'échéance — le collectif consent.
      </template>
      <template v-else>
        Des objections restaient ouvertes à l'échéance — le collectif ne consent pas encore.
      </template>
    </p>
  </section>
</template>

<style scoped>
.vc { padding: 1.25rem; display: flex; flex-direction: column; gap: 0.9rem; }
.vc__gestures { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
.vc__ok, .vc__no {
  display: flex; flex-direction: column; align-items: center; gap: 0.35rem;
  padding: 1.1rem 1rem; border-radius: var(--r-card); cursor: pointer;
  font-size: 1.0625rem; font-weight: 800;
  transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.vc__ok { background: color-mix(in srgb, var(--mood-success) 14%, var(--mood-surface)); color: var(--mood-success); }
.vc__no { background: color-mix(in srgb, var(--mood-warning) 13%, var(--mood-surface)); color: var(--mood-warning); }
.vc__ok:hover:not(:disabled), .vc__no:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 4px 12px var(--mood-shadow); }
.vc__ok:active, .vc__no:active { transform: translateY(0); }
.vc__ok:disabled, .vc__no:disabled { opacity: 0.55; cursor: not-allowed; }
.vc__gesture-icon { font-size: 1.4rem; }
.vc__done { font-size: 0.75rem; font-weight: 600; opacity: 0.8; }
.vc__argue { display: flex; flex-direction: column; gap: 0.5rem; }
.vc__argue textarea { padding: 0.6rem 0.8rem; font-size: 0.9375rem; resize: vertical; }
.vc__argue .ld-btn { align-self: flex-end; }
.vc__error { margin: 0; font-size: 0.875rem; font-weight: 600; color: var(--mood-error); }
.vc__tally { display: flex; align-items: center; flex-wrap: wrap; gap: 0.9rem; }
.vc__count { font-size: 0.9375rem; color: var(--mood-text-muted); }
.vc__count strong { color: var(--mood-text); font-size: 1.0625rem; }
.vc__objections { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.vc__objection { background: var(--mood-bg); border-radius: var(--r-input); padding: 0.6rem 0.85rem; font-size: 0.9rem; }
.vc__objection--open { background: color-mix(in srgb, var(--mood-warning) 9%, var(--mood-bg)); }
.vc__objection p { margin: 0.25rem 0 0; }
.vc__objection-state {
  font-size: 0.75rem; font-weight: 700; color: var(--mood-warning);
  text-transform: uppercase; letter-spacing: 0.04em; margin-right: 0.5rem;
}
.vc__objection-state--lifted { color: var(--mood-success); }
.vc__objection-who { font-weight: 700; font-size: 0.8125rem; }
.vc__resolution { color: var(--mood-text-muted); font-style: italic; }
.vc__outcome { margin: 0; font-weight: 600; font-size: 0.9375rem; }
@media (max-width: 480px) {
  .vc__gestures { grid-template-columns: 1fr; }
}
</style>
