import { expect } from "@esm-bundle/chai";
import sinon from "sinon";
import { MissionManager } from "../../src/managers/MissionManager.js";
import { narrativeManager } from "../../src/managers/NarrativeManager.js";

describe("Manager: MissionManager", () => {
  let manager;
  let mockNarrativeManager;
  let mockPersistence;

  beforeEach(() => {
    // Create mock persistence
    mockPersistence = {
      loadUnlocks: sinon.stub().resolves([]),
      saveUnlocks: sinon.stub().resolves(),
    };

    manager = new MissionManager(mockPersistence);

    // Mock narrativeManager
    mockNarrativeManager = {
      startSequence: sinon.stub(),
      addEventListener: sinon.stub(),
      removeEventListener: sinon.stub(),
    };

    // Replace the singleton reference in the manager if possible
    // Since it's imported, we'll need to stub the methods we use
    sinon.stub(narrativeManager, "startSequence");
    sinon.stub(narrativeManager, "addEventListener");
    sinon.stub(narrativeManager, "removeEventListener");
  });

  afterEach(() => {
    sinon.restore();
  });

  it("CoA 1: Should initialize with tutorial mission registered", async () => {
    await manager._ensureMissionsLoaded();
    expect(manager.missionRegistry.has("MISSION_TUTORIAL_01")).to.be.true;
    expect(manager.activeMissionId).to.be.null;
    expect(manager.completedMissions).to.be.instanceof(Set);
  });

  it("CoA 2: registerMission should add mission to registry", () => {
    const newMission = {
      id: "MISSION_TEST_01",
      config: { title: "Test Mission" },
      objectives: { primary: [] },
    };

    manager.registerMission(newMission);

    expect(manager.missionRegistry.has("MISSION_TEST_01")).to.be.true;
    expect(manager.missionRegistry.get("MISSION_TEST_01")).to.equal(newMission);
  });

  it("CoA 3: getActiveMission should return tutorial if no active mission", async () => {
    await manager._ensureMissionsLoaded();
    const mission = await manager.getActiveMission();

    expect(mission).to.exist;
    expect(mission.id).to.equal("MISSION_TUTORIAL_01");
  });

  it("CoA 4: getActiveMission should return active mission if set", async () => {
    const testMission = {
      id: "MISSION_TEST_01",
      config: { title: "Test" },
      objectives: { primary: [] },
    };
    manager.registerMission(testMission);
    manager.activeMissionId = "MISSION_TEST_01";

    const mission = await manager.getActiveMission();

    expect(mission.id).to.equal("MISSION_TEST_01");
  });

  it("CoA 5: setupActiveMission should initialize objectives", async () => {
    await manager._ensureMissionsLoaded();
    const mission = await manager.getActiveMission();
    mission.objectives = {
      primary: [
        { type: "ELIMINATE_ALL", target_count: 5 },
        { type: "ELIMINATE_UNIT", target_def_id: "ENEMY_GOBLIN", target_count: 3 },
      ],
    };

    await manager.setupActiveMission();

    expect(manager.currentObjectives).to.have.length(2);
    expect(manager.currentObjectives[0].current).to.equal(0);
    expect(manager.currentObjectives[0].complete).to.be.false;
    expect(manager.currentObjectives[1].target_count).to.equal(3);
  });

  it("CoA 6: onGameEvent should complete ELIMINATE_ALL when all enemies are dead", () => {
    const mockUnitManager = {
      activeUnits: new Map([
        ["PLAYER_1", { id: "PLAYER_1", team: "PLAYER", currentHealth: 100 }],
      ]),
      getUnitsByTeam: sinon.stub().returns([]), // No enemies left
    };

    manager.setUnitManager(mockUnitManager);
    manager.setupActiveMission();
    manager.currentObjectives = [
      { type: "ELIMINATE_ALL", complete: false },
    ];

    manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_1" });

    expect(manager.currentObjectives[0].complete).to.be.true;
  });

  it("CoA 7: onGameEvent should update ELIMINATE_UNIT objectives for specific unit", () => {
    manager.setupActiveMission();
    manager.currentObjectives = [
      {
        type: "ELIMINATE_UNIT",
        target_def_id: "ENEMY_GOBLIN",
        target_count: 2,
        current: 0,
        complete: false,
      },
    ];

    manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_GOBLIN" });
    manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_OTHER" }); // Should not count
    manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_GOBLIN" });

    expect(manager.currentObjectives[0].current).to.equal(2);
    expect(manager.currentObjectives[0].complete).to.be.true;
  });

  it("CoA 8: checkVictory should dispatch mission-victory event when all objectives complete", async () => {
    const victorySpy = sinon.spy();
    window.addEventListener("mission-victory", victorySpy);

    // Stub completeActiveMission to avoid async issues
    sinon.stub(manager, "completeActiveMission").resolves();

    manager.setupActiveMission();
    manager.currentObjectives = [
      { type: "ELIMINATE_ALL", target_count: 2, current: 2, complete: true },
    ];
    manager.activeMissionId = "MISSION_TUTORIAL_01";
    manager.currentMissionDef = {
      id: "MISSION_TUTORIAL_01",
      rewards: { guaranteed: {} },
    };

    manager.checkVictory();

    expect(victorySpy.called).to.be.true;
    expect(manager.completeActiveMission.called).to.be.true;

    window.removeEventListener("mission-victory", victorySpy);
  });

  it("CoA 9: completeActiveMission should add mission to completed set", async () => {
    manager.activeMissionId = "MISSION_TUTORIAL_01";
    manager.currentMissionDef = {
      id: "MISSION_TUTORIAL_01",
      rewards: { guaranteed: {} },
    };

    // Spy on window.dispatchEvent to verify campaign-data-changed event
    const eventSpy = sinon.spy();
    window.addEventListener("campaign-data-changed", eventSpy);

    await manager.completeActiveMission();

    expect(manager.completedMissions.has("MISSION_TUTORIAL_01")).to.be.true;
    expect(eventSpy.called).to.be.true;
    expect(eventSpy.firstCall.args[0].detail.missionCompleted).to.equal("MISSION_TUTORIAL_01");

    window.removeEventListener("campaign-data-changed", eventSpy);
  });

  it("CoA 10: load should restore completed missions", () => {
    const saveData = {
      completedMissions: ["MISSION_TUTORIAL_01", "MISSION_TEST_01"],
    };

    manager.load(saveData);

    expect(manager.completedMissions.has("MISSION_TUTORIAL_01")).to.be.true;
    expect(manager.completedMissions.has("MISSION_TEST_01")).to.be.true;
  });

  it("CoA 11: save should serialize completed missions", () => {
    manager.completedMissions.add("MISSION_TUTORIAL_01");
    manager.completedMissions.add("MISSION_TEST_01");

    const saved = manager.save();

    expect(saved.completedMissions).to.be.an("array");
    expect(saved.completedMissions).to.include("MISSION_TUTORIAL_01");
    expect(saved.completedMissions).to.include("MISSION_TEST_01");
  });

  it("CoA 12: _mapNarrativeIdToFileName should convert narrative IDs to filenames", () => {
    expect(manager._mapNarrativeIdToFileName("NARRATIVE_TUTORIAL_INTRO")).to.equal(
      "tutorial_intro"
    );
    expect(manager._mapNarrativeIdToFileName("NARRATIVE_TUTORIAL_SUCCESS")).to.equal(
      "tutorial_success"
    );
    // The implementation converts NARRATIVE_UNKNOWN to narrative_unknown (lowercase with NARRATIVE_ prefix removed)
    expect(manager._mapNarrativeIdToFileName("NARRATIVE_UNKNOWN")).to.equal("narrative_unknown");
  });

  it("CoA 13: getActiveMission should expose enemy_spawns from mission definition", () => {
    const missionWithEnemies = {
      id: "MISSION_TEST",
      config: { title: "Test Mission" },
      enemy_spawns: [
        { enemy_def_id: "ENEMY_SHARDBORN_SENTINEL", count: 2 },
      ],
      objectives: { primary: [] },
    };

    manager.registerMission(missionWithEnemies);
    manager.activeMissionId = "MISSION_TEST";

    const mission = manager.getActiveMission();

    expect(mission.enemy_spawns).to.exist;
    expect(mission.enemy_spawns).to.have.length(1);
    expect(mission.enemy_spawns[0].enemy_def_id).to.equal("ENEMY_SHARDBORN_SENTINEL");
    expect(mission.enemy_spawns[0].count).to.equal(2);
  });

  it("CoA 14: getActiveMission should expose deployment constraints with tutorial hints", () => {
    const missionWithDeployment = {
      id: "MISSION_TEST",
      config: { title: "Test Mission" },
      deployment: {
        suggested_units: ["CLASS_VANGUARD", "CLASS_AETHER_WEAVER"],
        tutorial_hint: "Drag units from the bench to the Green Zone.",
      },
      objectives: { primary: [] },
    };

    manager.registerMission(missionWithDeployment);
    manager.activeMissionId = "MISSION_TEST";

    const mission = manager.getActiveMission();

    expect(mission.deployment).to.exist;
    expect(mission.deployment.suggested_units).to.deep.equal([
      "CLASS_VANGUARD",
      "CLASS_AETHER_WEAVER",
    ]);
    expect(mission.deployment.tutorial_hint).to.equal(
      "Drag units from the bench to the Green Zone."
    );
  });

  describe("Failure Conditions", () => {
    it("CoA 15: Should trigger SQUAD_WIPE failure when all player units die", () => {
      const failureSpy = sinon.spy();
      window.addEventListener("mission-failure", failureSpy);

      const mockUnitManager = {
        activeUnits: new Map(), // No player units alive
        getUnitById: sinon.stub(),
        getUnitsByTeam: sinon.stub().returns([]), // No player units
      };

      manager.setUnitManager(mockUnitManager);
      manager.setupActiveMission();
      manager.failureConditions = [{ type: "SQUAD_WIPE" }];

      manager.checkFailureConditions("PLAYER_DEATH", { unitId: "PLAYER_1" });

      expect(failureSpy.called).to.be.true;
      expect(failureSpy.firstCall.args[0].detail.reason).to.equal("SQUAD_WIPE");

      window.removeEventListener("mission-failure", failureSpy);
    });

    it("CoA 16: Should trigger VIP_DEATH failure when VIP unit dies", () => {
      const failureSpy = sinon.spy();
      window.addEventListener("mission-failure", failureSpy);

      const mockUnit = {
        id: "VIP_1",
        team: "PLAYER",
        tags: ["VIP_ESCORT"],
      };

      const mockUnitManager = {
        getUnitById: sinon.stub().returns(mockUnit),
      };

      manager.setUnitManager(mockUnitManager);
      manager.failureConditions = [
        { type: "VIP_DEATH", target_tag: "VIP_ESCORT" },
      ];

      manager.checkFailureConditions("PLAYER_DEATH", { unitId: "VIP_1" });

      expect(failureSpy.called).to.be.true;
      expect(failureSpy.firstCall.args[0].detail.reason).to.equal("VIP_DEATH");

      window.removeEventListener("mission-failure", failureSpy);
    });

    it("CoA 17: Should trigger TURN_LIMIT_EXCEEDED failure when turn limit is exceeded", () => {
      const failureSpy = sinon.spy();
      window.addEventListener("mission-failure", failureSpy);

      manager.currentTurn = 11;
      manager.failureConditions = [{ type: "TURN_LIMIT_EXCEEDED", turn_limit: 10 }];

      manager.checkFailureConditions("TURN_END", {});

      expect(failureSpy.called).to.be.true;
      expect(failureSpy.firstCall.args[0].detail.reason).to.equal(
        "TURN_LIMIT_EXCEEDED"
      );

      window.removeEventListener("mission-failure", failureSpy);
    });
  });

  describe("Additional Objective Types", () => {
    it("CoA 18: Should complete SURVIVE objective when turn count is reached", () => {
      manager.setupActiveMission();
      manager.currentObjectives = [
        {
          type: "SURVIVE",
          turn_count: 5,
          current: 0,
          complete: false,
        },
      ];
      manager.currentTurn = 0;

      manager.updateTurn(5);
      manager.onGameEvent("TURN_END", { turn: 5 });

      expect(manager.currentObjectives[0].complete).to.be.true;
    });

    it("CoA 19: Should complete REACH_ZONE objective when unit reaches target zone", () => {
      manager.setupActiveMission();
      manager.currentObjectives = [
        {
          type: "REACH_ZONE",
          zone_coords: [{ x: 5, y: 0, z: 5 }],
          complete: false,
        },
      ];

      manager.onGameEvent("UNIT_MOVE", {
        position: { x: 5, y: 0, z: 5 },
      });

      expect(manager.currentObjectives[0].complete).to.be.true;
    });

    it("CoA 20: Should complete INTERACT objective when unit interacts with target object", () => {
      manager.setupActiveMission();
      manager.currentObjectives = [
        {
          type: "INTERACT",
          target_object_id: "OBJECT_LEVER",
          complete: false,
        },
      ];

      manager.onGameEvent("INTERACT", { objectId: "OBJECT_LEVER" });

      expect(manager.currentObjectives[0].complete).to.be.true;
    });

    it("CoA 21: Should complete ELIMINATE_ALL when all enemies are eliminated", () => {
      // Mock UnitManager with only player units (no enemies)
      const mockUnitManager = {
        activeUnits: new Map([
          ["PLAYER_1", { id: "PLAYER_1", team: "PLAYER", currentHealth: 100 }],
        ]),
      };

      manager.setUnitManager(mockUnitManager);
      manager.setupActiveMission();
      manager.currentObjectives = [
        {
          type: "ELIMINATE_ALL",
          complete: false,
        },
      ];

      manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_1" });

      expect(manager.currentObjectives[0].complete).to.be.true;
    });

    it("CoA 22: Should complete SQUAD_SURVIVAL objective when minimum units survive", () => {
      const mockUnitManager = {
        activeUnits: new Map([
          ["PLAYER_1", { id: "PLAYER_1", team: "PLAYER", currentHealth: 100 }],
          ["PLAYER_2", { id: "PLAYER_2", team: "PLAYER", currentHealth: 100 }],
          ["PLAYER_3", { id: "PLAYER_3", team: "PLAYER", currentHealth: 100 }],
          ["PLAYER_4", { id: "PLAYER_4", team: "PLAYER", currentHealth: 100 }],
        ]),
        getUnitsByTeam: sinon.stub().returns([
          { id: "PLAYER_1", team: "PLAYER", currentHealth: 100 },
          { id: "PLAYER_2", team: "PLAYER", currentHealth: 100 },
          { id: "PLAYER_3", team: "PLAYER", currentHealth: 100 },
          { id: "PLAYER_4", team: "PLAYER", currentHealth: 100 },
        ]),
      };

      manager.setUnitManager(mockUnitManager);
      manager.setupActiveMission();
      manager.currentObjectives = [
        {
          type: "SQUAD_SURVIVAL",
          min_alive: 4,
          complete: false,
        },
      ];

      manager.onGameEvent("PLAYER_DEATH", { unitId: "PLAYER_5" });

      expect(manager.currentObjectives[0].complete).to.be.true;
    });
  });

  describe("Secondary Objectives", () => {
    it("CoA 23: Should track secondary objectives separately from primary", () => {
      const mission = {
        id: "MISSION_TEST",
        config: { title: "Test" },
        objectives: {
          primary: [{ type: "ELIMINATE_ALL", id: "PRIMARY_1" }],
          secondary: [
            { type: "SURVIVE", turn_count: 10, id: "SECONDARY_1" },
          ],
        },
      };

      manager.registerMission(mission);
      manager.activeMissionId = "MISSION_TEST";
      manager.setupActiveMission();

      expect(manager.currentObjectives).to.have.length(1);
      expect(manager.secondaryObjectives).to.have.length(1);
      expect(manager.secondaryObjectives[0].id).to.equal("SECONDARY_1");
    });

    it("CoA 24: Should update secondary objectives on game events", () => {
      manager.setupActiveMission();
      manager.secondaryObjectives = [
        {
          type: "SURVIVE",
          turn_count: 3,
          current: 0,
          complete: false,
        },
      ];
      manager.currentTurn = 0;

      manager.updateTurn(3);
      manager.onGameEvent("TURN_END", { turn: 3 });

      expect(manager.secondaryObjectives[0].complete).to.be.true;
    });
  });

  describe("Reward Distribution", () => {
    beforeEach(() => {
      // Clear localStorage before each test
      localStorage.clear();
    });

    it("CoA 25: Should distribute guaranteed rewards on mission completion", () => {
      const rewardSpy = sinon.spy();
      window.addEventListener("mission-rewards", rewardSpy);

      manager.activeMissionId = "MISSION_TEST";
      manager.currentMissionDef = {
        id: "MISSION_TEST",
        rewards: {
          guaranteed: {
            xp: 500,
            currency: { aether_shards: 200 },
            items: ["ITEM_ELITE_BLAST_PLATE"],
            unlocks: ["CLASS_SAPPER"],
          },
        },
      };

      manager.distributeRewards();

      expect(rewardSpy.called).to.be.true;
      const rewardData = rewardSpy.firstCall.args[0].detail;
      expect(rewardData.xp).to.equal(500);
      expect(rewardData.currency.aether_shards).to.equal(200);
      expect(rewardData.items).to.include("ITEM_ELITE_BLAST_PLATE");
      expect(rewardData.unlocks).to.include("CLASS_SAPPER");

      window.removeEventListener("mission-rewards", rewardSpy);
    });

    it("CoA 26: Should distribute conditional rewards for completed secondary objectives", () => {
      const rewardSpy = sinon.spy();
      window.addEventListener("mission-rewards", rewardSpy);

      manager.activeMissionId = "MISSION_TEST";
      manager.currentMissionDef = {
        id: "MISSION_TEST",
        rewards: {
          guaranteed: { xp: 100 },
          conditional: [
            {
              objective_id: "OBJ_TIME_LIMIT",
              reward: { currency: { aether_shards: 100 } },
            },
          ],
        },
      };
      manager.secondaryObjectives = [
        {
          id: "OBJ_TIME_LIMIT",
          complete: true,
        },
      ];

      manager.distributeRewards();

      const rewardData = rewardSpy.firstCall.args[0].detail;
      expect(rewardData.currency.aether_shards).to.equal(100);

      window.removeEventListener("mission-rewards", rewardSpy);
    });

    it("CoA 27: Should unlock classes and store in IndexedDB", async () => {
      await manager.unlockClasses(["CLASS_TINKER", "CLASS_SAPPER"]);

      expect(mockPersistence.saveUnlocks.calledOnce).to.be.true;
      const savedUnlocks = mockPersistence.saveUnlocks.firstCall.args[0];
      expect(savedUnlocks).to.include("CLASS_TINKER");
      expect(savedUnlocks).to.include("CLASS_SAPPER");
    });

    it("CoA 28: Should merge new unlocks with existing unlocks", async () => {
      // Set up existing unlocks
      mockPersistence.loadUnlocks.resolves(["CLASS_VANGUARD"]);

      await manager.unlockClasses(["CLASS_TINKER"]);

      expect(mockPersistence.saveUnlocks.calledOnce).to.be.true;
      const savedUnlocks = mockPersistence.saveUnlocks.firstCall.args[0];
      expect(savedUnlocks).to.include("CLASS_VANGUARD");
      expect(savedUnlocks).to.include("CLASS_TINKER");
    });

    it("CoA 29: Should distribute faction reputation rewards", () => {
      const rewardSpy = sinon.spy();
      window.addEventListener("mission-rewards", rewardSpy);

      manager.activeMissionId = "MISSION_TEST";
      manager.currentMissionDef = {
        id: "MISSION_TEST",
        rewards: {
          guaranteed: {},
          faction_reputation: {
            IRON_LEGION: 50,
            COGWORK_CONCORD: -10,
          },
        },
      };

      manager.distributeRewards();

      const rewardData = rewardSpy.firstCall.args[0].detail;
      expect(rewardData.factionReputation.IRON_LEGION).to.equal(50);
      expect(rewardData.factionReputation.COGWORK_CONCORD).to.equal(-10);

      window.removeEventListener("mission-rewards", rewardSpy);
    });
  });

  describe("Mission Conclusion", () => {
    it("CoA 30: completeActiveMission should mark mission as completed", async () => {
      manager.activeMissionId = "MISSION_TEST";
      manager.currentMissionDef = {
        id: "MISSION_TEST",
        rewards: { guaranteed: {} },
      };

      await manager.completeActiveMission();

      expect(manager.completedMissions.has("MISSION_TEST")).to.be.true;
    });

    it("CoA 31: completeActiveMission should play outro narrative if available", async () => {
      const outroPromise = Promise.resolve();
      sinon.stub(manager, "playOutro").returns(outroPromise);

      manager.activeMissionId = "MISSION_TEST";
      manager.currentMissionDef = {
        id: "MISSION_TEST",
        narrative: { outro_success: "NARRATIVE_TUTORIAL_SUCCESS" },
        rewards: { guaranteed: {} },
      };

      await manager.completeActiveMission();

      expect(manager.playOutro.calledWith("NARRATIVE_TUTORIAL_SUCCESS")).to.be
        .true;
    });

    it("CoA 32: checkVictory should not trigger if not all primary objectives complete", () => {
      const victorySpy = sinon.spy();
      window.addEventListener("mission-victory", victorySpy);

      manager.setupActiveMission();
      manager.currentObjectives = [
        { type: "ELIMINATE_ALL", complete: true },
        { type: "SURVIVE", turn_count: 5, complete: false },
      ];
      manager.activeMissionId = "MISSION_TEST";

      manager.checkVictory();

      expect(victorySpy.called).to.be.false;

      window.removeEventListener("mission-victory", victorySpy);
    });

    it("CoA 33: checkVictory should include objective data in victory event", async () => {
      const victorySpy = sinon.spy();
      window.addEventListener("mission-victory", victorySpy);

      // Stub completeActiveMission to avoid async issues
      sinon.stub(manager, "completeActiveMission").resolves();

      manager.setupActiveMission();
      manager.currentObjectives = [
        { type: "ELIMINATE_ALL", complete: true, id: "OBJ_1" },
      ];
      manager.secondaryObjectives = [
        { type: "SURVIVE", complete: true, id: "OBJ_2" },
      ];
      manager.activeMissionId = "MISSION_TEST";
      manager.currentMissionDef = {
        id: "MISSION_TEST",
        rewards: { guaranteed: {} },
      };

      manager.checkVictory();

      expect(victorySpy.called).to.be.true;
      const detail = victorySpy.firstCall.args[0].detail;
      expect(detail.primaryObjectives).to.exist;
      expect(detail.secondaryObjectives).to.exist;

      window.removeEventListener("mission-victory", victorySpy);
    });
  });

  describe("UnitManager and TurnSystem Integration", () => {
    it("CoA 34: setUnitManager should store UnitManager reference", () => {
      const mockUnitManager = { activeUnits: new Map() };
      manager.setUnitManager(mockUnitManager);

      expect(manager.unitManager).to.equal(mockUnitManager);
    });

    it("CoA 35: setTurnSystem should store TurnSystem reference", () => {
      const mockTurnSystem = { round: 1 };
      manager.setTurnSystem(mockTurnSystem);

      expect(manager.turnSystem).to.equal(mockTurnSystem);
    });

    it("CoA 36: updateTurn should update current turn count", () => {
      manager.updateTurn(5);
      expect(manager.currentTurn).to.equal(5);

      manager.updateTurn(10);
      expect(manager.currentTurn).to.equal(10);
    });

    it("CoA 37: setupActiveMission should initialize failure conditions", () => {
      const mission = {
        id: "MISSION_TEST",
        config: { title: "Test" },
        objectives: {
          primary: [],
          failure_conditions: [
            { type: "SQUAD_WIPE" },
            { type: "VIP_DEATH", target_tag: "VIP_ESCORT" },
          ],
        },
      };

      manager.registerMission(mission);
      manager.activeMissionId = "MISSION_TEST";
      manager.setupActiveMission();

      expect(manager.failureConditions).to.have.length(2);
      expect(manager.failureConditions[0].type).to.equal("SQUAD_WIPE");
      expect(manager.failureConditions[1].type).to.equal("VIP_DEATH");
    });
  });

  describe("Lazy Loading", () => {
    it("CoA 31: Should lazy-load missions on first access", async () => {
      // Create a fresh manager to test lazy loading
      const freshManager = new MissionManager(mockPersistence);
      
      // Initially, registry should be empty (missions not loaded)
      expect(freshManager.missionRegistry.size).to.equal(0);

      // Trigger lazy loading
      await freshManager._ensureMissionsLoaded();

      // Now missions should be loaded
      expect(freshManager.missionRegistry.size).to.be.greaterThan(0);
      expect(freshManager.missionRegistry.has("MISSION_TUTORIAL_01")).to.be.true;
    });

    it("CoA 32: Should not reload missions if already loaded", async () => {
      // Load missions first time
      await manager._ensureMissionsLoaded();
      const firstSize = manager.missionRegistry.size;

      // Load again - should not duplicate
      await manager._ensureMissionsLoaded();
      const secondSize = manager.missionRegistry.size;

      expect(firstSize).to.equal(secondSize);
    });

    it("CoA 33: Should handle lazy loading errors gracefully", async () => {
      // Create a manager with a failing persistence (if needed)
      const freshManager = new MissionManager(mockPersistence);
      
      // Should not throw even if missions fail to load
      try {
        await freshManager._ensureMissionsLoaded();
        // If we get here, it handled gracefully
        expect(true).to.be.true;
      } catch (error) {
        // If error occurs, it should be handled
        expect(error).to.exist;
      }
    });
  });
});

