// 行级 diff（LCS）—— 用于 prompt 控制面"选某版 vs 当前激活版"的差异预览。
// 纯函数、无依赖，便于单测。

export type DiffOp = "eq" | "add" | "del";
export interface DiffLine {
  op: DiffOp; // eq=两侧相同 / add=仅在 b（新增）/ del=仅在 a（删除）
  text: string;
}

// lineDiff(a, b)：把 a → b 的逐行变化展开。基于最长公共子序列。
export function lineDiff(a: string, b: string): DiffLine[] {
  const al = a.split("\n");
  const bl = b.split("\n");
  const n = al.length;
  const m = bl.length;

  // LCS 长度表：lcs[i][j] = al[i:] 与 bl[j:] 的最长公共子序列长度。
  const lcs: number[][] = Array.from({ length: n + 1 }, () => new Array<number>(m + 1).fill(0));
  for (let i = n - 1; i >= 0; i--) {
    for (let j = m - 1; j >= 0; j--) {
      lcs[i][j] = al[i] === bl[j] ? lcs[i + 1][j + 1] + 1 : Math.max(lcs[i + 1][j], lcs[i][j + 1]);
    }
  }

  // 回溯：相同→eq；否则按 LCS 走向决定 del（消耗 a）还是 add（消耗 b）。
  const out: DiffLine[] = [];
  let i = 0;
  let j = 0;
  while (i < n && j < m) {
    if (al[i] === bl[j]) {
      out.push({ op: "eq", text: al[i] });
      i++;
      j++;
    } else if (lcs[i + 1][j] >= lcs[i][j + 1]) {
      out.push({ op: "del", text: al[i] });
      i++;
    } else {
      out.push({ op: "add", text: bl[j] });
      j++;
    }
  }
  while (i < n) out.push({ op: "del", text: al[i++] });
  while (j < m) out.push({ op: "add", text: bl[j++] });
  return out;
}

// diffStat：统计新增/删除行数（给 UI 角标"+3 -1"）。
export function diffStat(lines: DiffLine[]): { add: number; del: number } {
  let add = 0;
  let del = 0;
  for (const l of lines) {
    if (l.op === "add") add++;
    else if (l.op === "del") del++;
  }
  return { add, del };
}
