import { describe, expect, it } from "vitest";
import { buildCollections, MODE_COPY, selectRandomBoss } from "./data";
import { selectRandomBossPair } from "../game/roguelike";
import { GROUP_DROP_TABLES, createEmptyCollectionLog } from "../game/progression/loot";
import { AVAILABLE_BOSS_IDS, BOSS_GROUPS } from "../game/bossCatalog";

describe("game mode configuration", () => {
  it("separates randomized PVE from selectable Dungeons", () => {
    expect(MODE_COPY["roguelike-pve"].title).toBe("PVE");
    expect(MODE_COPY["rogue-trials"].detail).toContain("Endless");
    expect(MODE_COPY.dungeons.title).toBe("Dungeons");
  });

  it("selects a boss across the full encounter pool", () => {
    for (let index = 0; index < AVAILABLE_BOSS_IDS.length; index += 1) {
      expect(selectRandomBoss(() => (index + 0.5) / AVAILABLE_BOSS_IDS.length)).toBe(AVAILABLE_BOSS_IDS[index]);
    }
  });

  it("selects two distinct bosses for PVE", () => {
    const values = [0, 0];
    const pair = selectRandomBossPair([], () => values.shift() ?? 0);
    expect(pair).toEqual(["bulldrome", "sandglass-scorpion"]);
    expect(new Set(pair)).toHaveLength(2);
  });

  it("derives group collection entries from canonical group drop tables", () => {
    const collections = buildCollections(createEmptyCollectionLog(), {});
    expect(collections.map((group) => group.groupId)).toEqual(BOSS_GROUPS.map((group) => group.id));
    expect(collections.flatMap((group) => group.bosses.map((boss) => boss.bossId)).sort()).toEqual([...AVAILABLE_BOSS_IDS].sort());
    for (const collection of collections) {
      expect(collection.drops.map((drop) => drop.id)).toEqual(
        GROUP_DROP_TABLES[collection.groupId].entries.map((drop) => drop.id),
      );
    }
  });

  it("derives trophy ownership from the saved boss pet collection", () => {
    const collections = buildCollections({ dropsFound: {}, petsFound: { "bulldrome-pet": 1 } }, { bulldrome: 37 });
    const bulldrome = collections.flatMap((group) => group.bosses).find((boss) => boss.bossId === "bulldrome");
    expect(bulldrome?.pet.count).toBe(1);
    expect(bulldrome?.pet.chance).toBe("1 in 500");
    expect(bulldrome?.kills).toBe(37);
  });
});
