import { describe, expect, it } from "vitest";
import { createClassInventory } from "../healers";
import { useGameStore } from "../store";
import { createEncounterGearModifiers } from "./gearEffects";
import { GEAR_RECIPES, createDefaultGearProgress } from "./gear";
import {
  equipActiveInfusion,
  equipPassiveInfusion,
  infusionCosts,
  PASSIVE_INFUSIONS,
  passiveInfusionUnlocked,
} from "./infusions";
import { bossGroupDrop, groupDrop, type MaterialStack } from "./loot";
import { RUN_BUFF_ORDER } from "../roguelike";

function stack(item: ReturnType<typeof groupDrop>, quantity: number): MaterialStack {
  return { id: item.id, name: item.name, rarity: item.rarity, itemLevel: item.itemLevel, glyph: item.glyph, quantity };
}

describe("IWT2-style gear infusions", () => {
  it("offers all 18 roguelike buffs as passive infusion choices", () => {
    expect(PASSIVE_INFUSIONS.map((passive) => passive.id)).toEqual(RUN_BUFF_ORDER);
  });
  it("requires a +5 anchor and atomically spends five Ascendant plus five Mythic group drops", () => {
    const progress = createDefaultGearProgress();
    progress.brann.slots.weapon.level = 5;
    const costs = infusionCosts("brann", "weapon", "brann-unbreakable");
    const inventory = [
      stack(bossGroupDrop("bristlequake-boar", "ascendant"), 6),
      stack(groupDrop(GEAR_RECIPES.brann.weapon.primaryGroupId, "mythic"), 6),
    ];

    const result = equipActiveInfusion(progress, inventory, "brann", "weapon", "brann-unbreakable");
    expect(costs.map((cost) => cost.quantity)).toEqual([5, 5]);
    expect(result.inventory.map((item) => item.quantity)).toEqual([1, 1]);
    expect(result.gearProgress.brann.infusionAbilityId).toBe("brann-unbreakable");
    expect(progress.brann.infusionAbilityId).toBeNull();
  });

  it("rejects locked anchors and infusions owned by another hero", () => {
    const progress = createDefaultGearProgress();
    progress.brann.slots.chest.level = 5;
    expect(() => equipActiveInfusion(progress, [], "brann", "weapon", "brann-unbreakable")).toThrow("Selected anchor");
    expect(() => equipActiveInfusion(progress, [], "brann", "chest", "nia-quickdraw")).toThrow("does not belong");
  });

  it("compiles active effects into encounter modifiers once", () => {
    const progress = createDefaultGearProgress();
    progress.brann.slots.weapon.level = 5;
    progress.brann.infusionAbilityId = "brann-unbreakable";
    progress.nia.slots.weapon.level = 5;
    progress.nia.infusionAbilityId = "nia-hunters-mark";
    const modifiers = createEncounterGearModifiers(progress, "priest");
    expect(modifiers.brann.stunDuration).toBe(0);
    expect(modifiers.nia.damage).toBeCloseTo(1.08 * 1.2);
  });

  it("unlocks one free healer passive globally at +10 and applies it next encounter", () => {
    const progress = createDefaultGearProgress();
    progress.vale.slots.feet.level = 10;
    expect(passiveInfusionUnlocked(progress)).toBe(true);
    const infused = equipPassiveInfusion(progress, "priest", "mend-efficiency");
    useGameStore.getState().configureHealer("priest", "Aelia", createClassInventory("priest"), "bulldrome", "encounter", infused);
    expect(useGameStore.getState().runModifiers.mendManaMultiplier).toBe(0.75);
    expect(useGameStore.getState().runBuffRanks).toEqual({});
    expect(useGameStore.getState().passiveRunBuffId).toBe("mend-efficiency");
  });
});
