// 一键采纳改法：把审稿提议的补丁（original→replacement）应用到终稿。
// 纯逻辑（可单测，不依赖 DOM）。粒度=最小句段；找不到原文则不动正文（作者手改）。

export type FixOutcome =
  | { status: "applied"; text: string } // 命中原文并替换：text=改后终稿
  | { status: "not-found"; text: string } // 有补丁但终稿里找不到原文（作者已改稿/漂移）：text 原样
  | { status: "no-patch"; text: string }; // 该冲突无可自动应用的补丁：text 原样

// 已确认可应用的补丁（original/replacement 均为 string）。
export interface ApplicablePatch {
  original: string;
  replacement: string;
}

// 松散补丁入参：original/replacement 可能缺失/为 null（审稿可局部修复时才带上）。
interface LoosePatch {
  original: string | null | undefined;
  replacement: string | null | undefined;
}

// 是否带可应用补丁：original 非空 + replacement 为字符串（容许空串=删除）。
// 类型谓词：命中即把 original/replacement 收窄为 string，调用方无需强转。
export function hasApplicableFix(patch: LoosePatch): patch is ApplicablePatch {
  return (
    typeof patch.original === "string" &&
    patch.original.length > 0 &&
    typeof patch.replacement === "string"
  );
}

// 把首个匹配的 original 替换为 replacement（不可变：返回新串，不改入参）。
// 无补丁 → no-patch；有补丁但未命中 → not-found（终稿不变）；命中 → applied。
export function applyConflictFix(
  text: string,
  original: string | null | undefined,
  replacement: string | null | undefined,
): FixOutcome {
  const patch: LoosePatch = { original, replacement };
  if (!hasApplicableFix(patch)) {
    return { status: "no-patch", text };
  }
  // 谓词已把 patch 收窄为 ApplicablePatch，original/replacement 皆为 string。
  const idx = text.indexOf(patch.original);
  if (idx === -1) {
    return { status: "not-found", text };
  }
  return {
    status: "applied",
    text:
      text.slice(0, idx) +
      patch.replacement +
      text.slice(idx + patch.original.length),
  };
}
