import { beforeEach, describe, expect, it } from "vitest";
import { createClassAbilityLoadout, HEALER_ABILITIES, HEALER_ABILITY_IDS, HEALER_CLASSES, HEALER_CLASS_ORDER, resolveSlottedAbility } from "./healers";
import { healingEffect } from "./healerEffects";
import { useGameStore } from "./store";

describe("composable healer ability loadouts", () => {
  beforeEach(() => {
    useGameStore.getState().configureHealer("priest", "Aelia", []);
  });

  it("projects every class kit through the flat spell registry", () => {
    for (const classId of HEALER_CLASS_ORDER) {
      const loadout = createClassAbilityLoadout(classId);
      for (const [slotId, definition] of Object.entries(HEALER_CLASSES[classId].abilities)) {
        expect(resolveSlottedAbility(loadout, slotId as keyof typeof loadout)).toBe(HEALER_ABILITIES[definition.id]);
      }
    }
    expect(new Set(HEALER_ABILITY_IDS).size).toBe(HEALER_ABILITY_IDS.length);
    expect(Object.keys(HEALER_ABILITIES)).toEqual(HEALER_ABILITY_IDS);
  });

  it("casts a spell assigned outside its native class and slot", () => {
    useGameStore.getState().setAbilityLoadout({ ability1: "shaman-riptide" });
    useGameStore.getState().startEncounter();
    useGameStore.getState().selectMember("brann");

    expect(useGameStore.getState().castAbility("ability1")).toBe(true);
    expect(healingEffect(useGameStore.getState().party[1], "riptide")).toBeDefined();
  });

  it("resolves cast completion from recorded spell identity after cross-slot assignment", () => {
    useGameStore.getState().setAbilityLoadout({ ability6: "druid-regrowth" });
    useGameStore.getState().startEncounter();
    useGameStore.setState((state) => ({
      party: state.party.map((member) => member.id === "brann" ? { ...member, hp: 50 } : member),
    }));
    useGameStore.getState().selectMember("brann");

    expect(useGameStore.getState().castAbility("ability6")).toBe(true);
    useGameStore.getState().tick(0.51);

    const brann = useGameStore.getState().party[1];
    expect(brann.hp).toBeGreaterThan(50);
    expect(healingEffect(brann, "regrowth")).toBeDefined();
  });
});
