import { describe, expect, it } from "vitest";
import type { StoredArtifactRecord } from "../types/storage";
import { mergeIdentity, mergeRescannedArtifacts, substatName } from "./artifactMerge";

function record(overrides: Partial<StoredArtifactRecord> = {}): StoredArtifactRecord {
  return {
    id: "x",
    name: "Gladiator's Nostalgia",
    slot: "Flower of Life",
    level: 0,
    setName: "Gladiator's Finale",
    mainStat: "HP",
    mainValue: "717",
    substats: ["CRIT DMG+5.4%", "ATK+19", "HP%+4.1%", "Energy Recharge+5.2%"],
    equipped: "Not detected",
    confidence: 80,
    needsReview: false,
    source: "auto-scan",
    ...overrides,
  };
}

describe("artifactMerge", () => {
  it("strips values to get the substat name", () => {
    expect(substatName("CRIT DMG+13.2%")).toBe("CRIT DMG");
    expect(substatName("ATK+19")).toBe("ATK");
  });

  it("identity ignores level and substat values", () => {
    const low = record({ level: 0, substats: ["CRIT DMG+5.4%", "ATK+19"] });
    const high = record({ level: 20, substats: ["CRIT DMG+13.2%", "ATK+37"] });
    expect(mergeIdentity(low)).toBe(mergeIdentity(high));
  });

  it("collapses a leveled re-scan into one record, keeping the higher level", () => {
    const low = record({ id: "a", level: 0, timesSeen: 1 });
    const high = record({
      id: "b",
      level: 20,
      timesSeen: 1,
      substats: ["CRIT DMG+13.2%", "ATK+37", "HP%+15.7%", "Energy Recharge+11.7%"],
      equipped: "Bennett",
    });
    const { merged, collapsed } = mergeRescannedArtifacts([low, high]);
    expect(collapsed).toBe(1);
    expect(merged).toHaveLength(1);
    expect(merged[0].level).toBe(20);
    expect(merged[0].equipped).toBe("Bennett");
    expect(merged[0].timesSeen).toBe(2);
  });

  it("does not merge pieces with different substat lineups", () => {
    const threeLine = record({ id: "a", substats: ["CRIT DMG+5.4%", "ATK+19", "HP%+4.1%"] });
    const fourLine = record({ id: "b", substats: ["CRIT DMG+5.4%", "ATK+19", "HP%+4.1%", "DEF+16"] });
    const { merged, collapsed } = mergeRescannedArtifacts([threeLine, fourLine]);
    expect(collapsed).toBe(0);
    expect(merged).toHaveLength(2);
  });

  it("keeps distinct sets/slots/mains apart", () => {
    const flower = record({ slot: "Flower of Life", mainStat: "HP" });
    const plume = record({ slot: "Plume of Death", mainStat: "ATK" });
    const { merged } = mergeRescannedArtifacts([flower, plume]);
    expect(merged).toHaveLength(2);
  });

  it("preserves the earliest firstSeenAt and latest lastSeenAt", () => {
    const older = record({ id: "a", level: 0, firstSeenAt: "2026-01-01", lastSeenAt: "2026-01-02" });
    const newer = record({ id: "b", level: 20, firstSeenAt: "2026-06-01", lastSeenAt: "2026-06-10" });
    const { merged } = mergeRescannedArtifacts([older, newer]);
    expect(merged[0].firstSeenAt).toBe("2026-01-01");
    expect(merged[0].lastSeenAt).toBe("2026-06-10");
  });
});
