import type { PartialLayout } from './types';
import { compareBreaksLexicographically } from '../core/index';

function compareTieKey(a: number[], b: number[]): number {
  const n = Math.min(a.length, b.length);
  for (let i = 0; i < n; i++) {
    const av = a[i] ?? 0;
    const bv = b[i] ?? 0;
    if (av < bv) return -1;
    if (av > bv) return 1;
  }
  if (a.length < b.length) return -1;
  if (a.length > b.length) return 1;
  return 0;
}

/**
 * TopK 排序（确定性）：
 * - score 越大越优
 * - tieKey 越小越优（按 11 节构造的数值 key）
 * - breaks 字典序更小者更优（11.0A）
 */
export function compareLayouts(a: PartialLayout, b: PartialLayout): number {
  if (a.score !== b.score) return b.score - a.score;
  const t = compareTieKey(a.tieKey, b.tieKey);
  if (t !== 0) return t;
  return compareBreaksLexicographically(a.breaks, b.breaks);
}

function breaksKey(breaks: number[]): string {
  // breaks 序列作为去重 key（确定性）
  return breaks.join(',');
}

/**
 * 插入 TopK（去重 + 排序 + 截断）。
 *
 * 去重规则：
 * - 同 breaks 仅保留最优（score 更高；若相同按 tieKey/breaks 比较）
 */
export function insertTopK(list: PartialLayout[], cand: PartialLayout, k: number): PartialLayout[] {
  const K = Math.max(1, k | 0);
  const out = list.slice();

  const key = breaksKey(cand.breaks);
  const idx = out.findIndex((x) => breaksKey(x.breaks) === key);
  if (idx >= 0) {
    const existing = out[idx]!;
    if (compareLayouts(cand, existing) < 0) {
      // cand 更差，忽略
      return out;
    }
    out[idx] = cand;
  } else {
    out.push(cand);
  }

  out.sort(compareLayouts);
  if (out.length > K) out.length = K;
  return out;
}

