// Micara bridge — décision « pastille parle » (t_5b5992c1)
//
// Module PUR (aucun DOM, aucun timer) : à chaque bascule du dominant du
// mixer, quels messages {type:'speaking'} émettre vers le serveur, et quel
// locuteur doit s'arrêter après le hold (~1 s) s'il n'est pas remplacé.
// Le moteur (engine.js) applique le résultat : envoi immédiat des émissions,
// puis arme un setTimeout pour le stop différé si `stopAfterHold` est fourni.
//
// Règles (mute style Teams / pastille « parle ») :
// 1. Un téléphone devient dominant → il « parle » (émission immédiate), et
//    l'ancien locuteur s'arrête immédiatement (bascule A→B : A false, B true).
// 2. Silence (dominant null) ou micro de l'ORDI (localId) dominant → l'ancien
//    locuteur téléphone garde sa pastille pendant le hold (~1 s) puis s'arrête
//    — anti-clignotement entre deux prises de parole rapprochées.
// 3. Le même téléphone reprend la parole pendant le hold → rien à émettre
//    (il « parle » toujours) ; le moteur annule le stop différé.
// 4. Un canal est retiré (téléphone parti) → le moteur émet le stop immédiat
//    lui-même (voir engine.js removeChannel) — pas de cas ici.
//
// Retour : { emit: [{phoneId, speaking}], stopAfterHold: phoneId|null,
//            nextSpeakingId: phoneId|null }

export function speakingTransitions({ nextDominant, speakingId, localId }) {
  const emit = [];
  let nextSpeakingId = speakingId;
  let stopAfterHold = null;
  // « téléphone » = id non vide et différent du micro de l'ordi (l'admin
  // n'apparaît pas dans la liste des participants du dashboard)
  const isPhone = (id) => !!id && id !== localId;

  if (isPhone(nextDominant)) {
    if (nextDominant !== speakingId) {
      if (speakingId) emit.push({ phoneId: speakingId, speaking: false });
      emit.push({ phoneId: nextDominant, speaking: true });
      nextSpeakingId = nextDominant;
    }
    // même locuteur → aucun message (le moteur a annulé le stop différé)
  } else {
    // silence ou micro de l'ordi : l'ancien locuteur téléphone s'arrête
    // après le hold (~1 s) — sauf s'il reprend la parole avant.
    if (speakingId) {
      stopAfterHold = speakingId;
      nextSpeakingId = speakingId; // conservé pendant le hold
    }
  }
  return { emit, stopAfterHold, nextSpeakingId };
}
