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

import {
  initialReviewState,
  parseReviewBlock,
  reduceReview,
  type ReviewSseEvent,
} from "./sse";

const FULL_ISSUE = {
  character: "沈砚",
  aspect: "动机一致性",
  where: "第3段",
  quote: "他忽然转身。",
  diagnosis: "动机断裂",
  suggestion: "扣回护妹动机",
  confidence: 0.82,
};

describe("parseReviewBlock — characterization (灵感③ advisory)", () => {
  it("parses a characterization frame with a full issue", () => {
    const evt = parseReviewBlock(
      `event:characterization\ndata:{"issues":[${JSON.stringify(FULL_ISSUE)}]}`,
    );
    expect(evt).toEqual({
      event: "characterization",
      data: { issues: [FULL_ISSUE] },
    });
  });

  it("defaults missing issue fields (advisory 韧性)", () => {
    const evt = parseReviewBlock(
      'event:characterization\ndata:{"issues":[{"character":"阿黎"}]}',
    );
    expect(evt).toEqual({
      event: "characterization",
      data: {
        issues: [
          {
            character: "阿黎",
            aspect: "",
            where: "",
            quote: "",
            diagnosis: "",
            suggestion: "",
            confidence: 0,
          },
        ],
      },
    });
  });

  it("parses an empty issues frame (无明显问题降级)", () => {
    expect(
      parseReviewBlock('event:characterization\ndata:{"issues":[]}'),
    ).toEqual({ event: "characterization", data: { issues: [] } });
  });

  it("drops non-record issues without dropping the whole frame", () => {
    const evt = parseReviewBlock(
      'event:characterization\ndata:{"issues":["junk",{"character":"沈砚"}]}',
    );
    expect(evt?.event).toBe("characterization");
    if (evt?.event === "characterization") {
      expect(evt.data.issues).toHaveLength(1);
      expect(evt.data.issues[0]?.character).toBe("沈砚");
    }
  });
});

describe("reduceReview — characterization (replace-style like pace)", () => {
  it("sets characterization report and marks reviewing", () => {
    const evt: ReviewSseEvent = {
      event: "characterization",
      data: { issues: [FULL_ISSUE] },
    };
    const out = reduceReview(initialReviewState, evt);
    expect(out.phase).toBe("reviewing");
    expect(out.characterization).toEqual({ issues: [FULL_ISSUE] });
  });

  it("replaces (not accumulates) the characterization report", () => {
    const first = reduceReview(initialReviewState, {
      event: "characterization",
      data: { issues: [FULL_ISSUE] },
    });
    const second = reduceReview(first, {
      event: "characterization",
      data: { issues: [] },
    });
    expect(second.characterization).toEqual({ issues: [] });
  });

  it("leaves characterization untouched on a section event", () => {
    const seeded = reduceReview(initialReviewState, {
      event: "characterization",
      data: { issues: [FULL_ISSUE] },
    });
    const out = reduceReview(seeded, {
      event: "section",
      data: { name: "characterization", status: "done" },
    });
    expect(out.characterization).toEqual({ issues: [FULL_ISSUE] });
    expect(out.sections).toEqual([
      { name: "characterization", status: "done" },
    ]);
  });
});
