import { describe, expect, it } from "vitest";
import { useGameStore } from "./store";

describe("runtime performance budgets", () => {
  it.each([
    { label: "dual-boss", bossIds: ["emberfox", "sandglass-scorpion"] as const, maxElapsedMs: 3_500 },
    { label: "Rogue Trials trio", bossIds: ["emberfox", "sandglass-scorpion", "tempestscale-dragon"] as const, maxElapsedMs: 5_000 },
  ])("keeps ten minutes of $label simulation bounded", ({ bossIds, maxElapsedMs }) => {
    const store = useGameStore.getState();
    store.configureHealer("priest", "Perf", [], bossIds);
    store.startEncounter();
    useGameStore.setState((state) => ({
      boss: { ...state.boss, hp: 1_000_000_000, maxHp: 1_000_000_000 },
      additionalBosses: state.additionalBosses.map((entry) => ({
        ...entry,
        boss: { ...entry.boss, hp: 1_000_000_000, maxHp: 1_000_000_000 },
      })),
      party: state.party.map((member) => ({ ...member, absorb: 1_000_000_000 })),
    }));

    let maxHazards = 0;
    let maxDamageEvents = 0;
    let maxCombatLog = 0;
    const startedAt = performance.now();
    for (let step = 0; step < 6_000; step += 1) {
      useGameStore.getState().tick(0.1);
      const state = useGameStore.getState();
      const hazards = state.bossMotion.hazards.length
        + state.additionalBosses.reduce((sum, entry) => sum + entry.motion.hazards.length, 0);
      maxHazards = Math.max(maxHazards, hazards);
      maxDamageEvents = Math.max(maxDamageEvents, state.partyDamageEvents.length);
      maxCombatLog = Math.max(maxCombatLog, state.combatLog.length);
    }
    const elapsedMs = performance.now() - startedAt;
    const result = useGameStore.getState();

    expect(result.phase).toBe("combat");
    expect(result.time).toBeCloseTo(600, 5);
    expect(maxHazards).toBeLessThanOrEqual(64);
    expect(maxDamageEvents).toBeLessThanOrEqual(24);
    expect(maxCombatLog).toBeLessThanOrEqual(12);
    expect(elapsedMs).toBeLessThan(maxElapsedMs);
  });
});
