/**
 * 按 previousHash → currentHash 拓扑顺序排列日志。
 *
 * 写入侧通过 previousHash 显式串链，与 when 时间戳精度无关；
 * 拓扑遍历恢复写入顺序，避免 timestamptz(3) ms tie-break 不稳定带来的伪破链。
 *
 * 链断或缺失节点：从可达起点（previousHash=null/'GENESIS'）走到无后继为止，
 * 剩余不可达节点按原序追加到尾部（让 verifyHashChain 仍能标 HASH_CHAIN_BROKEN）。
 * 起点不存在时整体 fallback 到原序，由 verifyHashChain 报 INVALID_GENESIS。
 *
 * 抽出独立文件（无 path alias / 无 NestJS 依赖）方便 scripts/probes/ 直接 import 跑纯逻辑校验。
 */
export function orderLogsByHashChain<
  T extends { id: string; previousHash: string | null; currentHash: string },
>(logs: T[]): T[] {
  if (logs.length <= 1) return logs;

  const byPrevHash = new Map<string, T>();
  for (const log of logs) {
    const key = log.previousHash ?? 'GENESIS';
    if (!byPrevHash.has(key)) byPrevHash.set(key, log);
  }

  const ordered: T[] = [];
  const seen = new Set<string>();
  let cursor = byPrevHash.get('GENESIS');
  while (cursor && !seen.has(cursor.id)) {
    ordered.push(cursor);
    seen.add(cursor.id);
    cursor = byPrevHash.get(cursor.currentHash);
  }

  if (ordered.length === 0) return logs;

  for (const log of logs) {
    if (!seen.has(log.id)) ordered.push(log);
  }
  return ordered;
}
