// Sélection de lignes d'une `DataTable` en **mode serveur** : deux fonctions pures, et une
// seule idée — une sélection n'a de sens que sur la page qui l'a produite.
//
// Le composant reste monté d'une page à l'autre (changer de cible, charger la page suivante,
// poser un filtre : c'est la même route, le même arbre React), donc son état survit à des
// données entièrement renouvelées. Sans garde, « 10 sélectionnés » continuait de s'afficher
// après un changement de cible et l'action de masse s'appliquait à dix mots-clés devenus
// invisibles — versés, par exemple, dans une liste d'un autre marché (review T5).
//
// La parade est double, à dessein : `pageKey` **vide** la sélection dès que la page change,
// `visibleSelection` **restreint** ce qui en sort aux lignes réellement affichées. La
// première tient l'affichage honnête, la seconde rend le geste dangereux impossible même si
// la première venait à manquer un cas.

// Séparateur impossible dans un UUID : deux découpages différents ne peuvent pas se recoller
// (`["a|b"]` et `["a", "b"]` doivent rendre deux clés distinctes). Écrit en **séquence
// d'échappement** et jamais en octet brut : un NUL littéral fait classer le fichier « binaire »
// par git, qui le sort alors de tous les diffs — donc de toute review.
const SEPARATOR = "\u0000";

/**
 * Identité de la page affichée : sa **portée** (la cible du réservoir, par exemple) et les
 * lignes qu'elle contient. Deux rendus qui rendent la même clé montrent la même chose — et
 * seulement alors la sélection peut légitimement survivre.
 */
export function pageKey(scope: string, rowIds: readonly string[]): string {
  return [scope, ...rowIds].join(SEPARATOR);
}

/**
 * Les identifiants cochés **qui figurent sur la page**, dans l'ordre de la page.
 *
 * C'est cette liste, jamais les clés brutes de l'état de sélection, qu'une action de masse
 * doit recevoir : une ligne absente de l'écran ne peut pas être l'objet d'un geste que
 * l'utilisateur croit voir.
 */
export function visibleSelection(
  selection: Record<string, boolean>,
  rowIds: readonly string[],
): string[] {
  return rowIds.filter((id) => selection[id] === true);
}
