import { describe, expect, it } from "vitest";
import type { ReviewSampleRecord } from "../types/global";
import { reviewSampleToEvalCase, reviewSamplesToEvalCases } from "./reviewSampleCorpus";

function record(overrides: Partial<ReviewSampleRecord["sample"]> = {}, savedAt = "2026-07-05T10:00:00.000Z"): ReviewSampleRecord {
  return {
    savedAt,
    sample: {
      reason: "automatic:low-confidence",
      parsed: {
        name: "Gladiator's Nostalgia",
        slot: "Flower of Life",
        level: 20,
        mainStat: "HP",
        mainValue: "4,780",
        setName: "Gladiator's Finale",
        equipped: "Bennett",
        substats: ["CRIT DMG+12.4%", "ATK+9.9%"],
      },
      capture: {
        width: 2560,
        height: 1440,
        ocr: [
          { id: "artifact-title", label: "t", text: "Gladiator's Nostalgia\nFlower of Life", confidence: 80 },
          { id: "artifact-main-stat", label: "m", text: "HP\n4,780", confidence: 80 },
        ],
      },
      ...overrides,
    },
  };
}

describe("reviewSampleToEvalCase", () => {
  it("extracts ocr text and parser guesses as an unconfirmed case", () => {
    const evalCase = reviewSampleToEvalCase(record());
    expect(evalCase).not.toBeNull();
    expect(evalCase?.confirmed).toBe(false);
    expect(evalCase?.ocr["artifact-title"]).toContain("Gladiator's Nostalgia");
    expect(evalCase?.expect.slot).toBe("Flower of Life");
    expect(evalCase?.expect.level).toBe(20);
    expect(evalCase?.meta?.source).toBe("review-sample");
    expect(evalCase?.meta?.resolution).toBe("2560x1440");
  });

  it("drops Unknown/Not detected sentinels so they are not treated as labels", () => {
    const evalCase = reviewSampleToEvalCase(
      record({
        parsed: {
          name: "Unknown artifact",
          slot: "Circlet of Logos",
          mainStat: "Unknown main stat",
          mainValue: "?",
          setName: "Unknown set",
          equipped: "Not detected",
        },
      }),
    );
    expect(evalCase?.expect.name).toBeUndefined();
    expect(evalCase?.expect.mainStat).toBeUndefined();
    expect(evalCase?.expect.setName).toBeUndefined();
    expect(evalCase?.expect.equipped).toBeUndefined();
    // "?" mainValue is a sentinel non-answer, must not leak in as a label.
    expect(evalCase?.expect.mainValue).toBeUndefined();
    expect(evalCase?.expect.slot).toBe("Circlet of Logos");
  });

  it("returns null when the sample has no OCR", () => {
    expect(reviewSampleToEvalCase({ savedAt: "x", sample: { capture: { ocr: [] } } })).toBeNull();
    expect(reviewSampleToEvalCase({ savedAt: "x" })).toBeNull();
  });

  it("maps a list of records and skips empty ones", () => {
    const cases = reviewSamplesToEvalCases([record(), { savedAt: "y" }, record({}, "2026-07-05T11:00:00.000Z")]);
    expect(cases).toHaveLength(2);
    expect(new Set(cases.map((entry) => entry.id)).size).toBe(2);
  });
});
