import { expect } from "@esm-bundle/chai";
import { GameViewport } from "../../src/ui/game-viewport.js";
import { gameStateManager } from "../../src/core/GameStateManager.js";

describe("UI: GameViewport", () => {
  let element;
  let container;

  beforeEach(() => {
    container = document.createElement("div");
    document.body.appendChild(container);
    element = document.createElement("game-viewport");
    container.appendChild(element);
  });

  afterEach(() => {
    // Clean up event listeners and reset state
    if (container.parentNode) {
      container.parentNode.removeChild(container);
    }
    // Reset gameStateManager.activeRunData
    if (gameStateManager) {
      gameStateManager.activeRunData = null;
    }
  });

  // Helper to wait for LitElement update
  async function waitForUpdate() {
    await element.updateComplete;
    // Give a small delay for DOM updates
    await new Promise((resolve) => setTimeout(resolve, 10));
  }

  // Helper to query shadow DOM
  function queryShadow(selector) {
    return element.shadowRoot?.querySelector(selector);
  }

  describe("Squad Updates", () => {
    it("should update squad from run-data-updated event", async () => {
      await waitForUpdate();

      const testSquad = [
        { id: "u1", name: "Valerius", classId: "CLASS_VANGUARD" },
        { id: "u2", name: "Aria", classId: "CLASS_AETHER_WEAVER" },
      ];

      // Dispatch run-data-updated event
      window.dispatchEvent(
        new CustomEvent("run-data-updated", {
          detail: {
            runData: {
              squad: testSquad,
            },
          },
        })
      );

      await waitForUpdate();

      expect(element.squad).to.deep.equal(testSquad);
    });

    it("should update squad from activeRunData when gamestate-changed fires", async () => {
      await waitForUpdate();

      const testSquad = [
        { id: "u1", name: "Valerius", classId: "CLASS_VANGUARD" },
        { id: "u2", name: "Aria", classId: "CLASS_AETHER_WEAVER" },
      ];

      // Set activeRunData
      gameStateManager.activeRunData = {
        squad: testSquad,
      };

      // Dispatch gamestate-changed event
      window.dispatchEvent(
        new CustomEvent("gamestate-changed", {
          detail: { newState: "STATE_DEPLOYMENT" },
        })
      );

      await waitForUpdate();

      expect(element.squad).to.deep.equal(testSquad);
    });

    it("should update squad from activeRunData in constructor", async () => {
      const testSquad = [
        { id: "u1", name: "Valerius", classId: "CLASS_VANGUARD" },
      ];

      // Set activeRunData before element is created
      gameStateManager.activeRunData = {
        squad: testSquad,
      };

      // Create new element (constructor will call #setupCombatStateUpdates)
      const newElement = document.createElement("game-viewport");
      container.appendChild(newElement);
      await newElement.updateComplete;
      await new Promise((resolve) => setTimeout(resolve, 10));

      expect(newElement.squad).to.deep.equal(testSquad);
      newElement.remove();
    });

    it("should pass squad to deployment-hud", async () => {
      await waitForUpdate();

      const testSquad = [
        { id: "u1", name: "Valerius", classId: "CLASS_VANGUARD" },
        { id: "u2", name: "Aria", classId: "CLASS_AETHER_WEAVER" },
      ];

      element.squad = testSquad;
      await waitForUpdate();

      const deploymentHud = queryShadow("deployment-hud");
      expect(deploymentHud).to.exist;
      expect(deploymentHud.squad).to.deep.equal(testSquad);
    });

    it("should handle empty squad gracefully", async () => {
      await waitForUpdate();

      expect(element.squad).to.be.an("array");
      expect(element.squad.length).to.equal(0);

      const deploymentHud = queryShadow("deployment-hud");
      expect(deploymentHud).to.exist;
      expect(deploymentHud.squad).to.be.an("array");
    });

    it("should create new array reference when updating squad", async () => {
      await waitForUpdate();

      const testSquad = [
        { id: "u1", name: "Valerius", classId: "CLASS_VANGUARD" },
      ];

      window.dispatchEvent(
        new CustomEvent("run-data-updated", {
          detail: {
            runData: {
              squad: testSquad,
            },
          },
        })
      );

      await waitForUpdate();

      // Verify it's a new array reference (not the same object)
      expect(element.squad).to.not.equal(testSquad);
      expect(element.squad).to.deep.equal(testSquad);
    });
  });
});


