import { describe, expect, it } from "vitest";
import type { StoredArtifactRecord } from "../types/storage";
import {
  goodDatabaseToStoredArtifacts,
  goodSubstatToString,
  goodToStoredArtifact,
  setKeyToName,
  setNameToKey,
  storedArtifactToGood,
  storedArtifactsToGood,
  substatStringToGood,
} from "./goodInterop";

const record: StoredArtifactRecord = {
  id: "x",
  name: "Gladiator's Nostalgia",
  slot: "Flower of Life",
  level: 20,
  setName: "Gladiator's Finale",
  mainStat: "HP",
  mainValue: "4,780",
  substats: ["CRIT DMG+13.2%", "ATK+19", "HP%+15.7%", "Energy Recharge+5.2%"],
  equipped: "Bennett",
  confidence: 90,
  needsReview: false,
  source: "auto-scan",
};

describe("goodInterop set keys", () => {
  it("converts set names to GOOD PascalCase keys", () => {
    expect(setNameToKey("Gladiator's Finale")).toBe("GladiatorsFinale");
    expect(setNameToKey("Viridescent Venerer")).toBe("ViridescentVenerer");
    expect(setNameToKey("Emblem of Severed Fate")).toBe("EmblemOfSeveredFate");
  });

  it("round-trips known set keys back to names", () => {
    for (const name of ["Gladiator's Finale", "Viridescent Venerer"]) {
      expect(setKeyToName(setNameToKey(name))).toBe(name);
    }
  });
});

describe("goodInterop substats", () => {
  it("parses percent and flat substat strings", () => {
    expect(substatStringToGood("CRIT DMG+13.2%")).toEqual({ key: "critDMG_", value: 13.2 });
    expect(substatStringToGood("ATK+19")).toEqual({ key: "atk", value: 19 });
    expect(substatStringToGood("HP%+15.7%")).toEqual({ key: "hp_", value: 15.7 });
  });

  it("returns null for unparseable substats", () => {
    expect(substatStringToGood("nonsense")).toBeNull();
    expect(substatStringToGood("Unknown+5")).toBeNull();
  });

  it("round-trips substat strings", () => {
    for (const entry of record.substats) {
      const good = substatStringToGood(entry)!;
      expect(goodSubstatToString(good)).toBe(entry);
    }
  });
});

describe("goodInterop export", () => {
  it("exports a stored artifact to GOOD", () => {
    const good = storedArtifactToGood(record);
    expect(good.setKey).toBe("GladiatorsFinale");
    expect(good.slotKey).toBe("flower");
    expect(good.mainStatKey).toBe("hp");
    expect(good.level).toBe(20);
    expect(good.rarity).toBe(5);
    expect(good.substats).toContainEqual({ key: "critDMG_", value: 13.2 });
  });

  it("wraps records in a GOOD database envelope", () => {
    const db = storedArtifactsToGood([record]);
    expect(db.format).toBe("GOOD");
    expect(db.artifacts).toHaveLength(1);
  });
});

describe("goodInterop import", () => {
  it("imports a GOOD artifact back to a stored record", () => {
    const good = storedArtifactToGood(record);
    const back = goodToStoredArtifact({ ...good, location: "Bennett" })!;
    expect(back.slot).toBe("Flower of Life");
    expect(back.setName).toBe("Gladiator's Finale");
    expect(back.mainStat).toBe("HP");
    expect(back.equipped).toBe("Bennett");
    expect(back.substats).toContain("CRIT DMG+13.2%");
    expect(back.source).toBe("good-import");
  });

  it("computes a main value from slot + main stat + level on import", () => {
    const good = storedArtifactToGood(record);
    const back = goodToStoredArtifact(good)!;
    // Flower HP main at +20 is the reference max; just assert it is populated.
    expect(back.mainValue).not.toBe("");
  });

  it("skips artifacts with an unknown slot or main stat", () => {
    expect(goodToStoredArtifact({ setKey: "GladiatorsFinale", slotKey: "bogus", mainStatKey: "hp" })).toBeNull();
    expect(goodToStoredArtifact({ setKey: "GladiatorsFinale", slotKey: "flower", mainStatKey: "bogus" })).toBeNull();
  });

  it("maps a full GOOD database", () => {
    const db = storedArtifactsToGood([record, { ...record, slot: "Plume of Death", mainStat: "ATK", mainValue: "311" }]);
    const imported = goodDatabaseToStoredArtifacts(db);
    expect(imported).toHaveLength(2);
    expect(imported.map((entry) => entry.slot)).toEqual(["Flower of Life", "Plume of Death"]);
  });
});
