<script setup lang="ts">
/**
 * « / — Aujourd'hui » : capture + Fil personnel — la boîte de réception de la
 * démocratie. Tout est sélecteur Pinia pur (useFeed) ; les sections vides sont
 * masquées ; le compteur est nu — jamais de rouge.
 */
import type { Decision } from '~/types/domain'
import {
  BOUNDARY_SUSPENDED,
  CRYSTALLIZE_CARD,
  DOSSIER_COMPLETE_CARD,
  FEED_HEADER,
  FIRST_DECISION,
  ICONS,
  MATURATION_CARD,
  REVIEW_TITLE,
  SCOPE_KEEP,
  SCOPE_WIDEN,
} from '~/lexicon'
import { useCollectiveStore } from '~/stores/collective'
import { useDecisionsStore } from '~/stores/decisions'
import { useFeed } from '~/composables/useFeed'

const col = useCollectiveStore()
const decisions = useDecisionsStore()
const {
  objectionWindows, adviceRequests, openVotes, toCrystallize, dossiersComplete,
  tiesToBreak, reviewsDue, mandateReportsDue, boundaryObjections,
  overflowingScopes, prioritiesAsked, suggestions, collectiveActivity, myCount,
} = useFeed()

const dossierError = ref('')

const allEmpty = computed(
  () => myCount.value === 0 && suggestions.value.length === 0
    && collectiveActivity.value.length === 0,
)

/** The proposed founding decision, still in preparation. */
const pactPending = computed(() =>
  col.decisions.some(d => d.title === FIRST_DECISION && d.status === 'draft'),
)

const decisionById = (id: string): Decision | undefined =>
  col.decisions.find(d => d.id === id)
const personName = (id: string): string =>
  col.people.find(p => p.id === id)?.displayName ?? 'Quelqu\'un'
const dateFr = (iso: string): string =>
  new Date(iso).toLocaleDateString('fr-FR', { day: 'numeric', month: 'long' })

/** Steward gesture: framing → closed once every element is terminal. */
function closeDossier(decision: Decision) {
  const res = decisions.transition(decision.id, 'closed')
  dossierError.value = res.ok ? '' : res.reason
}
</script>

<template>
  <!-- ld-v2 -->
  <div class="feed-page">
    <FeedCapture />

    <header class="feed-header">
      <h1 class="feed-header__title">{{ FEED_HEADER }}</h1>
      <span v-if="myCount > 0" class="feed-header__count">{{ myCount }}</span>
    </header>

    <!-- État vide global — invitation chaleureuse -->
    <div v-if="allEmpty" class="ld-card feed-empty">
      <UIcon name="i-lucide-sun-medium" class="feed-empty__icon" />
      <p class="feed-empty__line">
        Rien ne t'attend — c'est le bon moment pour capturer ta première décision.
      </p>
      <p class="feed-empty__hint">
        Une phrase suffit, là-haut. Le chemin s'occupe du reste.
      </p>
      <NuxtLink
        v-if="pactPending"
        class="ld-btn"
        :to="{ path: '/decider', query: { titre: FIRST_DECISION } }"
      >
        <UIcon name="i-lucide-feather" />
        <span>{{ FIRST_DECISION }}</span>
      </NuxtLink>
    </div>

    <template v-else>
      <!-- Frontières contestées — priorité haute, en tête -->
      <FeedSection
        v-if="boundaryObjections.length > 0"
        title="Frontières contestées — à traiter d'abord"
        icon="i-lucide-octagon-pause"
        priority
      >
        <FeedItemCard
          v-for="o in boundaryObjections"
          :key="o.id"
          :title="decisionById(o.decisionId)?.title ?? 'Décision'"
          icon="i-lucide-octagon-pause"
          tint="var(--mood-status-fenetre)"
          :to="`/decisions/${o.decisionId}`"
        >
          <template #meta>
            <span class="status-pill status-suspended">{{ BOUNDARY_SUSPENDED }}</span>
          </template>
          <p class="feed-quote">{{ personName(o.personId) }} : « {{ o.argument }} »</p>
        </FeedItemCard>
      </FeedSection>

      <!-- Fenêtres d'objection -->
      <FeedSection
        v-if="objectionWindows.length > 0"
        title="Fenêtres d'objection"
        icon="i-lucide-timer"
      >
        <FeedWindowCard v-for="d in objectionWindows" :key="d.id" :decision="d" />
      </FeedSection>

      <!-- Avis demandés -->
      <FeedSection
        v-if="adviceRequests.length > 0"
        title="Avis demandés"
        icon="i-lucide-message-circle"
      >
        <FeedAdviceCard v-for="d in adviceRequests" :key="d.id" :decision="d" />
      </FeedSection>

      <!-- Votes ouverts -->
      <FeedSection v-if="openVotes.length > 0" title="Votes ouverts" icon="i-lucide-users">
        <FeedVoteCard
          v-for="item in openVotes"
          :key="item.session.id"
          :session="item.session"
          :decision="item.decision"
        />
      </FeedSection>

      <!-- À cristalliser — le geste du garant -->
      <FeedSection v-if="toCrystallize.length > 0" title="À cristalliser" :icon="ICONS.crystallize">
        <FeedItemCard
          v-for="item in toCrystallize"
          :key="item.session.id"
          :title="item.decision?.title ?? 'Réglage collectif'"
          :icon="ICONS.crystallize"
          tint="var(--mood-accent)"
          :to="item.decision ? `/decisions/${item.decision.id}/vote` : undefined"
        >
          <p class="feed-line">{{ CRYSTALLIZE_CARD }}</p>
        </FeedItemCard>
      </FeedSection>

      <!-- Dossiers complets — clore est un geste -->
      <FeedSection v-if="dossiersComplete.length > 0" title="Dossiers complets" icon="i-lucide-folder-check">
        <FeedItemCard
          v-for="d in dossiersComplete"
          :key="d.id"
          :title="d.title"
          icon="i-lucide-folder-check"
          tint="var(--mood-status-vigueur)"
          :to="`/decisions/${d.id}`"
        >
          <p class="feed-line">{{ DOSSIER_COMPLETE_CARD }}</p>
          <p v-if="dossierError" class="feed-error">{{ dossierError }}</p>
          <template #actions>
            <button class="ld-btn feed-btn" type="button" @click="closeDossier(d)">
              <UIcon name="i-lucide-stamp" />
              <span>Clore et publier</span>
            </button>
          </template>
        </FeedItemCard>
      </FeedSection>

      <!-- Égalités à départager — jamais par l'outil -->
      <FeedSection v-if="tiesToBreak.length > 0" title="Égalités à départager" icon="i-lucide-scale">
        <FeedItemCard
          v-for="item in tiesToBreak"
          :key="item.session.id"
          :title="item.decision?.title ?? 'Élection'"
          icon="i-lucide-scale"
          tint="var(--mood-status-vote)"
          :to="item.decision ? `/decisions/${item.decision.id}` : undefined"
        >
          <p class="feed-line">Égalité constatée — vous départagez, jamais l'outil.</p>
        </FeedItemCard>
      </FeedSection>

      <!-- L'épreuve du réel -->
      <FeedSection v-if="reviewsDue.length > 0" :title="REVIEW_TITLE" icon="i-lucide-flask-conical">
        <FeedReviewCard v-for="d in reviewsDue" :key="d.id" :decision="d" />
      </FeedSection>

      <!-- Rapports de mandat -->
      <FeedSection v-if="mandateReportsDue.length > 0" title="Rapports de mandat" icon="i-lucide-key-round">
        <FeedItemCard
          v-for="item in mandateReportsDue"
          :key="item.mandate.id"
          :title="item.mandate.title"
          icon="i-lucide-key-round"
          tint="var(--route-mandate)"
          :to="`/mandats/${item.mandate.id}`"
        >
          <p class="feed-line">Un rapport est attendu depuis le {{ dateFr(item.dueAt) }}.</p>
        </FeedItemCard>
      </FeedSection>

      <!-- Périmètres qui débordent -->
      <FeedSection v-if="overflowingScopes.length > 0" title="Périmètres qui débordent" icon="i-lucide-expand">
        <FeedItemCard
          v-for="d in overflowingScopes"
          :key="d.id"
          :title="d.title"
          icon="i-lucide-expand"
          tint="var(--mood-status-fenetre)"
        >
          <p class="feed-line">Plus de monde se déclare concerné que prévu — décide du périmètre.</p>
          <template #actions>
            <NuxtLink class="ld-btn feed-btn" :to="`/decisions/${d.id}?geste=elargir`">
              {{ SCOPE_WIDEN }}
            </NuxtLink>
            <NuxtLink class="ld-btn ld-btn--ghost feed-btn" :to="`/decisions/${d.id}?geste=maintenir`">
              {{ SCOPE_KEEP }}
            </NuxtLink>
          </template>
        </FeedItemCard>
      </FeedSection>

      <!-- Pondère tes enjeux -->
      <FeedSection v-if="prioritiesAsked.length > 0" title="Pondère tes enjeux" icon="i-lucide-sliders-horizontal">
        <FeedItemCard
          v-for="c in prioritiesAsked"
          :key="c.id"
          :title="decisionById(c.decisionId)?.title ?? 'Élément de dossier'"
          icon="i-lucide-sliders-horizontal"
          tint="var(--mood-tertiary)"
          :to="`/decisions/${c.decisionId}`"
        >
          <p class="feed-line">Dis au dossier combien cet élément compte pour toi (0–3).</p>
        </FeedItemCard>
      </FeedSection>

      <!-- Boucle apprenante — cartes discrètes -->
      <FeedSection v-if="suggestions.length > 0" title="Boucle apprenante" icon="i-lucide-repeat" discrete>
        <template v-for="(s, i) in suggestions" :key="i">
          <FeedItemCard
            v-if="s.kind === 'claim-mandate'"
            :title="`${s.count}ᵉ fois sur « ${s.tags[0]} » — réclame un mandat`"
            :icon="ICONS.recurrence"
            to="/mandats/nouveau"
          />
          <FeedItemCard
            v-else-if="s.kind === 'protocolize'"
            :title="MATURATION_CARD"
            icon="i-lucide-sprout"
            to="/textes"
          >
            <p class="feed-line">{{ s.count }} consignations proches sur « {{ s.tags[0] }} ».</p>
          </FeedItemCard>
          <FeedItemCard
            v-else
            :title="`Le protocole « ${s.protocol.name} » n'a jamais servi — élague ?`"
            icon="i-lucide-scissors"
            to="/textes/formules"
          />
        </template>
      </FeedSection>

      <!-- Activité du collectif -->
      <FeedSection v-if="collectiveActivity.length > 0" title="Activité du collectif" icon="i-lucide-activity">
        <FeedActivityCard v-for="d in collectiveActivity" :key="d.id" :decision="d" />
      </FeedSection>
    </template>
  </div>
</template>

<style scoped>
.feed-page {
  width: 100%;
  max-width: 44rem;
  margin: 0 auto;
}
.feed-header {
  display: flex;
  align-items: baseline;
  gap: 0.625rem;
  margin: 0.75rem 0 1.25rem;
}
.feed-header__title {
  margin: 0;
  font-size: clamp(1.375rem, 4vw, 1.75rem);
  font-weight: 800;
  letter-spacing: -0.02em;
}
.feed-header__count {
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--mood-text-muted);
}
.feed-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: clamp(2rem, 6vw, 3.5rem) 1.5rem;
  text-align: center;
}
.feed-empty__icon { font-size: 2rem; color: var(--mood-accent); }
.feed-empty__line {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 700;
  max-width: 26rem;
}
.feed-empty__hint {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--mood-text-muted);
}
.feed-line { margin: 0; font-size: 0.875rem; color: var(--mood-text-muted); }
.feed-quote { margin: 0; font-size: 0.875rem; font-style: italic; }
.feed-error { margin: 0; font-size: 0.8125rem; color: var(--mood-error); }
.feed-btn { font-size: 0.875rem; padding: 0.4rem 1rem; text-decoration: none; }
</style>
