import { describe, expect, it } from "vitest";
import { HEALER_ABILITY_IDS } from "../healers";
import {
  buildRpgRoguelikeSpellPool,
  generateSpellDraftOffers,
  HEALER_SPELL_IDS,
  RPG_ROGUELIKE_SPELL_POLICY,
} from "./spells";
import { createRandomState } from "./random";
import { SPELL_OFFERS_PER_WAVE } from "./types";

describe("RPG Roguelike healer spell discovery", () => {
  it("automatically mirrors the canonical healer registry minus explicit blocks", () => {
    const blocked = new Set(RPG_ROGUELIKE_SPELL_POLICY.blockedSpellIds);
    expect(HEALER_SPELL_IDS).toEqual(HEALER_ABILITY_IDS.filter((spellId) => !blocked.has(spellId)));
  });

  it("supports a typed mode-specific deny-list without changing the healer registry", () => {
    const blockedSpellId = HEALER_ABILITY_IDS[0];
    const pool = buildRpgRoguelikeSpellPool(HEALER_ABILITY_IDS, { blockedSpellIds: [blockedSpellId] });

    expect(pool).not.toContain(blockedSpellId);
    expect(pool).toEqual(HEALER_ABILITY_IDS.slice(1));
    expect(HEALER_ABILITY_IDS).toContain(blockedSpellId);
  });

  it("never reintroduces blocked spells when unseen offers run low", () => {
    const blockedSpellId = HEALER_ABILITY_IDS[0];
    const eligible = buildRpgRoguelikeSpellPool(HEALER_ABILITY_IDS, { blockedSpellIds: [blockedSpellId] });
    const seen = eligible.slice(0, eligible.length - 1);
    const left = generateSpellDraftOffers(createRandomState("blocked-fallback"), seen, eligible);
    const right = generateSpellDraftOffers(createRandomState("blocked-fallback"), seen, eligible);

    expect(left).toEqual(right);
    expect(left.offers).toHaveLength(SPELL_OFFERS_PER_WAVE);
    expect(left.offers).not.toContain(blockedSpellId);
    expect(left.offers.every((spellId) => eligible.includes(spellId))).toBe(true);
  });

  it("fails clearly when policy leaves too few draftable abilities", () => {
    const minimal = HEALER_ABILITY_IDS.slice(0, SPELL_OFFERS_PER_WAVE);
    expect(() => buildRpgRoguelikeSpellPool(minimal, { blockedSpellIds: [minimal[0]] }))
      .toThrow(`RPG Roguelike needs at least ${SPELL_OFFERS_PER_WAVE} eligible healer abilities.`);
  });
});
