// Pure Reciprocal Rank Fusion (RRF). Combines several ranked id lists into one
// ranking by summing 1/(k + rank) for each id across the lists it appears in
// (rank is 1-based; k dampens the contribution of low ranks). This is a robust,
// score-free way to fuse heterogeneous signals (semantic + lexical) — only the
// ORDER of each input list matters, not its raw scores.
//
// No I/O, no platform deps — fully unit-testable.

/**
 * Fuse ordered id lists into a single ranking, highest fused score first.
 *
 * @param lists ordered id lists (rank 1 = first element of each list).
 * @param k     RRF damping constant (default 60, the canonical value).
 */
export function rrf(lists: string[][], k = 60): { id: string; score: number }[] {
  const scores = new Map<string, number>();

  for (const list of lists) {
    for (let i = 0; i < list.length; i++) {
      const id = list[i];
      if (id === undefined) continue;
      const rank = i + 1; // 1-based
      scores.set(id, (scores.get(id) ?? 0) + 1 / (k + rank));
    }
  }

  return [...scores.entries()]
    .map(([id, score]) => ({ id, score }))
    .sort((a, b) => b.score - a.score);
}
