import { describe, expect, it } from "vitest";

import { conflictSnippet, parseParagraphNo } from "./snippet";

describe("parseParagraphNo", () => {
  it("extracts 1-based paragraph number from 第 N 段 wording", () => {
    expect(parseParagraphNo("第 3 段，主角忽然示弱")).toBe(3);
    expect(parseParagraphNo("第9段老者道破来历")).toBe(9);
  });

  it("returns null when no paragraph number present", () => {
    expect(parseParagraphNo("战斗场景")).toBeNull();
    expect(parseParagraphNo("开篇提到三日后")).toBeNull();
    expect(parseParagraphNo("")).toBeNull();
  });

  it("takes the first number for a range like 第 4–6 段", () => {
    expect(parseParagraphNo("第 4–6 段反复描写天气")).toBe(4);
  });
});

describe("conflictSnippet", () => {
  const text = "第一段正文。\n\n第二段正文。\n\n第三段正文，命中冲突的句子。";

  it("returns the trimmed paragraph for a parseable where", () => {
    expect(conflictSnippet(text, "第 3 段，主角忽然示弱")).toBe(
      "第三段正文，命中冲突的句子。",
    );
  });

  it("returns null when paragraph number is unparseable", () => {
    expect(conflictSnippet(text, "战斗场景")).toBeNull();
  });

  it("returns null when paragraph index is out of range", () => {
    expect(conflictSnippet(text, "第 9 段")).toBeNull();
  });

  it("returns null when the located paragraph is empty", () => {
    expect(conflictSnippet("\n\n\n\n正文", "第 1 段")).toBeNull();
  });

  it("truncates long paragraphs with an ellipsis", () => {
    const long = "甲".repeat(200);
    const snippet = conflictSnippet(long, "第 1 段");
    expect(snippet).not.toBeNull();
    expect(snippet!.length).toBeLessThanOrEqual(81);
    expect(snippet!.endsWith("…")).toBe(true);
  });
});
