<script setup lang="ts">
/**
 * WorkflowMilestones — 11 jalons de protocole de fonctionnement.
 * Sélectif et qualitatif : ce qui fait la différence entre un protocole
 * qui tient et un qui dérive.
 * Référence : g1vote, sociocracie, Laloux, Elinor Ostrom (gouvernance des communs).
 */

interface Milestone {
  num: number
  name: string
  icon: string
  actor: string
  duration: { min: string; standard: string; major: string }
  description: string
  essential: boolean
  tip?: string
  ostrom?: string
}

const milestones: Milestone[] = [
  {
    num: 1,
    name: 'Prise d\'initiative',
    icon: 'i-lucide-lightbulb',
    actor: 'Tout membre',
    duration: { min: '—', standard: '1-2j', major: '1-2j' },
    description: 'Formaliser l\'intention : quel problème, quel besoin, quelle cible visée. Nommer un·e porteur·euse responsable.',
    essential: true,
    tip: 'Une initiative sans porteur identifié ne décolle pas. La responsabilité individuelle est le premier jalon.',
    ostrom: 'Principe 1 — Frontières claires : qui est concerné, pourquoi.',
  },
  {
    num: 2,
    name: 'Processus d\'avis (advice)',
    icon: 'i-lucide-message-circle',
    actor: 'Porteur + experts + impactés',
    duration: { min: '1j', standard: '3-7j', major: '7-14j' },
    description: 'Consulter les personnes qui ont l\'expertise ET celles qui seront impactées. Écouter vraiment, intégrer ou expliquer pourquoi on n\'intègre pas.',
    essential: true,
    tip: 'Ce jalon est souvent escamoté. C\'est la principale cause d\'échec ou de résistance en implémentation.',
    ostrom: 'Principe 5 — Résolution des conflits accessible et peu coûteuse.',
  },
  {
    num: 3,
    name: 'Rédaction + amendements',
    icon: 'i-lucide-file-edit',
    actor: 'Porteur + communauté',
    duration: { min: '1-2j', standard: '3-7j', major: '7-21j' },
    description: 'Rédiger la proposition formelle. Ouvrir une période d\'amendements publics. Intégrer les modifications acceptées, rejeter les autres avec justification.',
    essential: true,
    tip: 'Distinguer amendements substantiels (re-vote possible) et de forme (porteur décide).',
  },
  {
    num: 4,
    name: 'Qualification technique',
    icon: 'i-lucide-shield-check',
    actor: 'Comité technique (si applicable)',
    duration: { min: '—', standard: '2-5j', major: '5-10j' },
    description: 'Pour les décisions techniques : revue par les experts désignés. Évaluation de faisabilité, risques, impact. Avis formel (non bloquant, sauf veto défini).',
    essential: false,
    tip: 'Optionnel selon la nature de la décision. Systématique pour les Runtime Upgrades.',
  },
  {
    num: 5,
    name: 'Ouverture du vote',
    icon: 'i-lucide-vote',
    actor: 'Porteur + plateforme',
    duration: { min: '—', standard: '1j', major: '1j' },
    description: 'Publier la proposition finale. Notifier la communauté. Ouvrir la session de vote avec les paramètres définis (protocole, formule, durée).',
    essential: true,
    tip: 'L\'ouverture doit être annoncée à l\'avance (délai de préavis selon règlement).',
  },
  {
    num: 6,
    name: 'Phase de vote',
    icon: 'i-lucide-bar-chart-2',
    actor: 'Membres habilités',
    duration: { min: '3j', standard: '7-14j', major: '21-30j' },
    description: 'Les membres habilités votent selon le protocole. Seuil de participation minimal surveillé. Résultats intermédiaires visibles (ou non, selon le protocole).',
    essential: true,
    ostrom: 'Principe 3 — Choix collectifs : ceux qui sont concernés participent aux décisions.',
  },
  {
    num: 7,
    name: 'Contrôle du quorum',
    icon: 'i-lucide-check-circle',
    actor: 'Plateforme + porteur',
    duration: { min: '—', standard: '—', major: '—' },
    description: 'Vérifier que le quorum minimum est atteint avant clôture. Si non atteint : prolonger, relancer, ou annuler selon les règles préétablies.',
    essential: true,
    tip: 'Définir à l\'avance le quorum et la procédure si non atteint — évite les ambiguïtés.',
    ostrom: 'Principe 4 — Supervision des règles par les membres.',
  },
  {
    num: 8,
    name: 'Proclamation des résultats',
    icon: 'i-lucide-megaphone',
    actor: 'Plateforme + porteur',
    duration: { min: '—', standard: '1j', major: '1j' },
    description: 'Annoncer le résultat officiel avec les chiffres détaillés (votes pour, contre, abstentions, taux participation, seuil requis). Archiver on-chain si adopté.',
    essential: true,
    tip: 'La transparence des résultats est aussi importante que le résultat lui-même.',
    ostrom: 'Principe 8 — Gouvernance emboîtée : résultats remontés aux niveaux supérieurs.',
  },
  {
    num: 9,
    name: 'Mise en application',
    icon: 'i-lucide-play-circle',
    actor: 'Porteur + implémenteurs',
    duration: { min: '—', standard: 'Variable', major: 'Variable' },
    description: 'Planifier l\'application effective de la décision. Désigner les responsables. Fixer des jalons d\'implémentation si complexe.',
    essential: true,
    tip: 'Une décision adoptée mais non implémentée érode la confiance dans le processus.',
  },
  {
    num: 10,
    name: 'Suivi et accountability',
    icon: 'i-lucide-activity',
    actor: 'Porteur + communauté',
    duration: { min: '—', standard: 'Continu', major: 'Continu' },
    description: 'Rapports réguliers sur l\'avancement. Signalement des écarts. Mécanisme de remontée si la décision produit des effets inattendus.',
    essential: false,
    tip: 'Intégrer dans le prochain cycle de gouvernance si des ajustements s\'imposent.',
    ostrom: 'Principe 4 — Surveillance continue des comportements et résultats.',
  },
  {
    num: 11,
    name: 'Rétrospective',
    icon: 'i-lucide-rotate-ccw',
    actor: 'Cercle concerné',
    duration: { min: '—', standard: '1-2h', major: '1-2j' },
    description: 'Évaluer : le processus a-t-il bien fonctionné ? La décision produit-elle les effets attendus ? Quoi améliorer pour la prochaine fois ?',
    essential: false,
    tip: 'La rétrospective est le moteur d\'amélioration du protocole lui-même (méta-gouvernance).',
    ostrom: 'Principe 7 — Reconnaissance externe de l\'organisation par des autorités supérieures.',
  },
]

const showOstrom = ref(false)
const activeDecisionType = ref<'minor' | 'standard' | 'major'>('standard')

const decisionTypes = [
  { value: 'minor', label: 'Mineur', color: 'teal' },
  { value: 'standard', label: 'Standard', color: 'accent' },
  { value: 'major', label: 'Majeur', color: 'secondary' },
]

const essentialMilestones = computed(() =>
  milestones.filter(m => m.essential),
)

const optionalMilestones = computed(() =>
  milestones.filter(m => !m.essential),
)

const totalDuration = computed(() => {
  const type = activeDecisionType.value
  const durations = {
    minor: '5-10 jours',
    standard: '14-30 jours',
    major: '45-90 jours',
  }
  return durations[type]
})
</script>

<template>
  <div class="wm">
    <!-- Header -->
    <div class="wm__header">
      <h3 class="wm__title">Jalons de protocole</h3>
      <p class="wm__subtitle">
        11 jalons, dont 7 indispensables. Durées recommandées selon le type de décision.
      </p>
    </div>

    <!-- Decision type selector -->
    <div class="wm__type-selector">
      <button
        v-for="dt in decisionTypes"
        :key="dt.value"
        class="wm__type-btn"
        :class="[
          `wm__type-btn--${dt.color}`,
          { 'wm__type-btn--active': activeDecisionType === dt.value },
        ]"
        @click="activeDecisionType = dt.value as 'minor' | 'standard' | 'major'"
      >
        {{ dt.label }}
      </button>
      <span class="wm__total-duration">≈ {{ totalDuration }}</span>
    </div>

    <!-- Essential milestones -->
    <div class="wm__section">
      <div class="wm__section-label">
        <span class="wm__section-badge wm__section-badge--essential">7 essentiels</span>
      </div>
      <div class="wm__milestones">
        <div
          v-for="m in essentialMilestones"
          :key="m.num"
          class="wm__milestone wm__milestone--essential"
        >
          <div class="wm__milestone-left">
            <div class="wm__milestone-num">{{ m.num }}</div>
            <div v-if="m.num < milestones.length" class="wm__milestone-line" />
          </div>
          <div class="wm__milestone-icon">
            <UIcon :name="m.icon" />
          </div>
          <div class="wm__milestone-body">
            <div class="wm__milestone-head">
              <span class="wm__milestone-name">{{ m.name }}</span>
              <span class="wm__milestone-duration">
                {{ m.duration[activeDecisionType] || '—' }}
              </span>
            </div>
            <p class="wm__milestone-desc">{{ m.description }}</p>
            <div v-if="m.tip" class="wm__milestone-tip">
              <UIcon name="i-lucide-lightbulb" />
              {{ m.tip }}
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Optional milestones -->
    <div class="wm__section">
      <div class="wm__section-label">
        <span class="wm__section-badge wm__section-badge--optional">4 contextuels</span>
      </div>
      <div class="wm__milestones">
        <div
          v-for="m in optionalMilestones"
          :key="m.num"
          class="wm__milestone wm__milestone--optional"
        >
          <div class="wm__milestone-left">
            <div class="wm__milestone-num wm__milestone-num--optional">{{ m.num }}</div>
          </div>
          <div class="wm__milestone-icon wm__milestone-icon--optional">
            <UIcon :name="m.icon" />
          </div>
          <div class="wm__milestone-body">
            <div class="wm__milestone-head">
              <span class="wm__milestone-name">{{ m.name }}</span>
              <span class="wm__milestone-duration">
                {{ m.duration[activeDecisionType] || '—' }}
              </span>
            </div>
            <p class="wm__milestone-desc">{{ m.description }}</p>
          </div>
        </div>
      </div>
    </div>

    <!-- Ostrom toggle -->
    <button class="wm__ostrom-toggle" @click="showOstrom = !showOstrom">
      <UIcon name="i-lucide-book-open" />
      <span>Principes Ostrom appliqués</span>
      <UIcon :name="showOstrom ? 'i-lucide-chevron-up' : 'i-lucide-chevron-down'" />
    </button>

    <Transition name="expand">
      <div v-if="showOstrom" class="wm__ostrom">
        <p class="wm__ostrom-intro">
          Elinor Ostrom (Nobel 2009) a identifié 8 principes pour la gouvernance
          durable des communs. Les jalons ci-dessus les incarnent.
        </p>
        <div class="wm__ostrom-items">
          <div
            v-for="m in milestones.filter(x => x.ostrom)"
            :key="m.num"
            class="wm__ostrom-item"
          >
            <span class="wm__ostrom-jalon">Jalon {{ m.num }}</span>
            <span class="wm__ostrom-text">{{ m.ostrom }}</span>
          </div>
        </div>
      </div>
    </Transition>
  </div>
</template>

<style scoped>
.wm { display: flex; flex-direction: column; gap: 1rem; }

.wm__header { display: flex; flex-direction: column; gap: 0.25rem; }

.wm__title {
  font-size: 1rem;
  font-weight: 800;
  color: var(--mood-text);
  margin: 0;
}

.wm__subtitle {
  font-size: 0.8125rem;
  color: var(--mood-text-muted);
  margin: 0;
  line-height: 1.5;
}

/* Type selector */
.wm__type-selector {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  flex-wrap: wrap;
}

.wm__type-btn {
  padding: 0.375rem 0.875rem;
  font-size: 0.75rem;
  font-weight: 700;
  border-radius: 20px;
  cursor: pointer;
  background: var(--mood-accent-soft);
  color: var(--mood-text-muted);
  transition: all 0.12s ease;
}

.wm__type-btn--accent.wm__type-btn--active {
  background: var(--mood-accent);
  color: var(--mood-accent-text);
}

.wm__type-btn--teal.wm__type-btn--active {
  background: color-mix(in srgb, var(--mood-success) 20%, transparent);
  color: var(--mood-success);
}

.wm__type-btn--secondary.wm__type-btn--active {
  background: color-mix(in srgb, var(--mood-secondary, var(--mood-accent)) 20%, transparent);
  color: var(--mood-secondary, var(--mood-accent));
}

.wm__total-duration {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--mood-text-muted);
  margin-left: auto;
}

/* Section */
.wm__section { display: flex; flex-direction: column; gap: 0.5rem; }

.wm__section-label { display: flex; align-items: center; gap: 0.5rem; }

.wm__section-badge {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 10px;
  border-radius: 20px;
}

.wm__section-badge--essential {
  background: var(--mood-accent-soft);
  color: var(--mood-accent);
}

.wm__section-badge--optional {
  background: color-mix(in srgb, var(--mood-text-muted) 12%, transparent);
  color: var(--mood-text-muted);
}

/* Milestones */
.wm__milestones { display: flex; flex-direction: column; gap: 0; }

.wm__milestone {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  padding: 0.5rem 0;
}

.wm__milestone-left {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
  width: 1.375rem;
}

.wm__milestone-num {
  width: 1.375rem;
  height: 1.375rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--mood-accent);
  color: var(--mood-accent-text);
  font-size: 0.625rem;
  font-weight: 800;
  flex-shrink: 0;
  z-index: 1;
}

.wm__milestone-num--optional {
  background: color-mix(in srgb, var(--mood-text-muted) 20%, transparent);
  color: var(--mood-text-muted);
}

.wm__milestone-line {
  width: 2px;
  flex: 1;
  min-height: 1.25rem;
  background: color-mix(in srgb, var(--mood-accent) 20%, transparent);
  margin-top: 2px;
}

.wm__milestone-icon {
  width: 1.75rem;
  height: 1.75rem;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--mood-accent-soft);
  color: var(--mood-accent);
  font-size: 0.875rem;
}

.wm__milestone-icon--optional {
  background: color-mix(in srgb, var(--mood-text-muted) 10%, transparent);
  color: var(--mood-text-muted);
}

.wm__milestone-body {
  flex: 1;
  min-width: 0;
  padding-bottom: 0.625rem;
}

.wm__milestone-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.wm__milestone-name {
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--mood-text);
}

.wm__milestone--optional .wm__milestone-name {
  color: var(--mood-text-muted);
}

.wm__milestone-duration {
  font-size: 0.625rem;
  font-weight: 600;
  font-family: ui-monospace, SFMono-Regular, monospace;
  color: var(--mood-accent);
  background: var(--mood-accent-soft);
  padding: 1px 6px;
  border-radius: 20px;
}

.wm__milestone-desc {
  font-size: 0.75rem;
  color: var(--mood-text-muted);
  line-height: 1.5;
  margin: 0.125rem 0 0;
}

.wm__milestone-tip {
  display: flex;
  align-items: flex-start;
  gap: 0.375rem;
  margin-top: 0.375rem;
  padding: 0.375rem 0.5rem;
  background: color-mix(in srgb, var(--mood-accent) 8%, transparent);
  border-radius: 8px;
  font-size: 0.6875rem;
  color: var(--mood-accent);
  line-height: 1.5;
}

/* Ostrom */
.wm__ostrom-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.625rem 0.75rem;
  background: var(--mood-accent-soft);
  border-radius: 10px;
  cursor: pointer;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--mood-text-muted);
  transition: color 0.12s ease;
  text-align: left;
}
.wm__ostrom-toggle:hover { color: var(--mood-text); }
.wm__ostrom-toggle .i-lucide-book-open { color: var(--mood-accent); }

.wm__ostrom {
  background: var(--mood-accent-soft);
  border-radius: 12px;
  padding: 0.875rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.wm__ostrom-intro {
  font-size: 0.75rem;
  color: var(--mood-text-muted);
  line-height: 1.6;
  margin: 0;
}

.wm__ostrom-items {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.wm__ostrom-item {
  display: flex;
  gap: 0.625rem;
  font-size: 0.75rem;
  line-height: 1.5;
}

.wm__ostrom-jalon {
  font-weight: 700;
  color: var(--mood-accent);
  white-space: nowrap;
  flex-shrink: 0;
}

.wm__ostrom-text { color: var(--mood-text-muted); }

/* Expand transition */
.expand-enter-active, .expand-leave-active { transition: all 0.2s ease; overflow: hidden; }
.expand-enter-from, .expand-leave-to { max-height: 0; opacity: 0; }
.expand-enter-to, .expand-leave-from { max-height: 1000px; opacity: 1; }
</style>
