import { expect } from "@esm-bundle/chai";
import sinon from "sinon";
import { GameLoop } from "../../../src/core/GameLoop.js";
import {
  createGameLoopSetup,
  cleanupGameLoop,
  createRunData,
  createMockGameStateManagerForCombat,
  setupCombatUnits,
  cleanupTurnSystem,
} from "./helpers.js";

describe("Core: GameLoop - Combat Deployment Integration", function () {
  this.timeout(30000);

  let gameLoop;
  let container;
  let mockGameStateManager;
  let playerUnit;
  let enemyUnit;

  beforeEach(async () => {
    const setup = createGameLoopSetup();
    gameLoop = setup.gameLoop;
    container = setup.container;

    gameLoop.stop();
    if (
      gameLoop.turnSystem &&
      typeof gameLoop.turnSystem.reset === "function"
    ) {
      gameLoop.turnSystem.reset();
    }

    gameLoop.init(container);
    mockGameStateManager = createMockGameStateManagerForCombat();
    // Ensure rosterManager exists
    if (!mockGameStateManager.rosterManager) {
      mockGameStateManager.rosterManager = { roster: [] };
    }
    gameLoop.gameStateManager = mockGameStateManager;

    const runData = createRunData({
      squad: [{ id: "u1", classId: "CLASS_VANGUARD" }],
    });
    await gameLoop.startLevel(runData, { startAnimation: false });

    const units = setupCombatUnits(gameLoop);
    playerUnit = units.playerUnit;
    enemyUnit = units.enemyUnit;
  });

  afterEach(() => {
    gameLoop.clearMovementHighlights();
    gameLoop.clearSpawnZoneHighlights();
    cleanupTurnSystem(gameLoop);
    cleanupGameLoop(gameLoop, container);
  });

  it("CoA 14: should clear spawn zone highlights when deployment finishes", async () => {
    mockGameStateManager.currentState = "STATE_DEPLOYMENT";

    const runData = createRunData();
    await gameLoop.startLevel(runData, { startAnimation: false });

    expect(gameLoop.spawnZoneHighlights.size).to.be.greaterThan(0);
    gameLoop.finalizeDeployment();
    expect(gameLoop.spawnZoneHighlights.size).to.equal(0);
  });

  it("CoA 14b: should update combat state immediately when deployment finishes", async () => {
    mockGameStateManager.currentState = "STATE_DEPLOYMENT";

    const runData = createRunData({
      squad: [{ id: "u1", classId: "CLASS_VANGUARD" }],
    });
    await gameLoop.startLevel(runData, { startAnimation: false });

    const unitDef = runData.squad[0];
    const validTile = gameLoop.playerSpawnZone[0];
    gameLoop.deployUnit(unitDef, validTile);

    const updateCombatStateSpy = sinon.spy(gameLoop, "updateCombatState");
    gameLoop.finalizeDeployment();

    expect(updateCombatStateSpy.calledOnce).to.be.true;
    expect(mockGameStateManager.setCombatState.called).to.be.true;
    const combatStateCall = mockGameStateManager.setCombatState.getCall(-1);
    expect(combatStateCall).to.exist;
    const combatState = combatStateCall.args[0];
    expect(combatState).to.exist;
    expect(combatState.isActive).to.be.true;
    expect(combatState.turnQueue).to.be.an("array");

    updateCombatStateSpy.restore();
  });

  it("CoA 15: should clear movement highlights when starting new level", async () => {
    mockGameStateManager.getCombatState.returns({
      activeUnit: {
        id: playerUnit.id,
        name: playerUnit.name,
      },
      turnQueue: [],
    });
    gameLoop.updateMovementHighlights(playerUnit);
    expect(gameLoop.movementHighlights.size).to.be.greaterThan(0);

    const runData = createRunData({ seed: 99999 });
    await gameLoop.startLevel(runData, { startAnimation: false });

    expect(gameLoop.movementHighlights.size).to.equal(0);
  });
});
