import { expect } from "@esm-bundle/chai";
import { CharacterSheet } from "../../src/ui/components/CharacterSheet.js";
import { Explorer } from "../../src/units/Explorer.js";
import { Item } from "../../src/items/Item.js";
import vanguardDef from "../../src/assets/data/classes/vanguard.json" with {
  type: "json",
};

// Import SkillTreeUI to register the custom element
import "../../src/ui/components/SkillTreeUI.js";

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

  beforeEach(() => {
    container = document.createElement("div");
    document.body.appendChild(container);
    element = document.createElement("character-sheet");
    container.appendChild(element);

    // Create a test Explorer unit
    testUnit = new Explorer("test-unit-1", "Test Vanguard", "CLASS_VANGUARD", vanguardDef);
    testUnit.classMastery["CLASS_VANGUARD"] = {
      level: 5,
      xp: 250,
      skillPoints: 2,
      unlockedNodes: [],
    };
    testUnit.recalculateBaseStats(vanguardDef);
    testUnit.currentHealth = 100;
    testUnit.maxHealth = 120;
  });

  afterEach(() => {
    if (container.parentNode) {
      container.parentNode.removeChild(container);
    }
  });

  // 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);
  }

  function queryShadowAll(selector) {
    return element.shadowRoot?.querySelectorAll(selector) || [];
  }

  describe("CoA 1: Stat Rendering", () => {
    it("should render stats with effective values", async () => {
      element.unit = testUnit;
      await waitForUpdate();

      // Check that stat values are displayed
      const statValues = queryShadowAll('.stat-value');
      expect(statValues.length).to.be.greaterThan(0);
    });

    it("should show stat breakdown in tooltip on hover", async () => {
      element.unit = testUnit;
      await waitForUpdate();

      const statItem = queryShadow(".stat-item");
      expect(statItem).to.exist;

      const tooltip = statItem.querySelector(".tooltip");
      expect(tooltip).to.exist;
    });

    it("should display debuffed stats in red", async () => {
      testUnit.statusEffects = [
        {
          id: "WEAKNESS",
          name: "Weakness",
          statModifiers: { attack: -5 },
        },
      ];
      element.unit = testUnit;
      await waitForUpdate();

      const attackStat = Array.from(queryShadowAll(".stat-item")).find((item) =>
        item.textContent.includes("Attack")
      );
      expect(attackStat).to.exist;
      expect(attackStat.classList.contains("debuffed")).to.be.true;

      const statValue = attackStat.querySelector(".stat-value");
      expect(statValue.classList.contains("debuffed")).to.be.true;
    });

    it("should display buffed stats in green", async () => {
      testUnit.statusEffects = [
        {
          id: "STRENGTH",
          name: "Strength",
          statModifiers: { attack: +5 },
        },
      ];
      element.unit = testUnit;
      await waitForUpdate();

      const attackStat = Array.from(queryShadowAll(".stat-item")).find((item) =>
        item.textContent.includes("Attack")
      );
      expect(attackStat).to.exist;
      expect(attackStat.classList.contains("buffed")).to.be.true;

      const statValue = attackStat.querySelector(".stat-value");
      expect(statValue.classList.contains("buffed")).to.be.true;
    });

    it("should calculate effective stats from base + equipment + buffs", async () => {
      const weapon = new Item({
        id: "ITEM_TEST_SWORD",
        name: "Test Sword",
        type: "WEAPON",
        stats: { attack: 10 },
      });

      // Reset to level 1 to get base stats
      testUnit.classMastery["CLASS_VANGUARD"].level = 1;
      testUnit.recalculateBaseStats(vanguardDef);

      testUnit.equipment.weapon = weapon;
      testUnit.statusEffects = [
        {
          id: "BUFF",
          name: "Power Boost",
          statModifiers: { attack: 3 },
        },
      ];

      element.unit = testUnit;
      await waitForUpdate();

      // Base attack from vanguard level 1 is 12, +10 from weapon, +3 from buff = 25
      const attackStat = Array.from(queryShadowAll(".stat-item")).find((item) =>
        item.textContent.includes("Attack")
      );
      const statValue = attackStat.querySelector(".stat-value");
      const totalValue = parseInt(statValue.textContent.trim());
      expect(totalValue).to.equal(25);
    });

    it("should display health bar with current/max values", async () => {
      testUnit.currentHealth = 80;
      testUnit.maxHealth = 120;
      element.unit = testUnit;
      await waitForUpdate();

      const healthBar = queryShadow(".health-bar-container");
      expect(healthBar).to.exist;

      const healthLabel = queryShadow(".health-label");
      expect(healthLabel.textContent).to.include("80");
      expect(healthLabel.textContent).to.include("120");
    });

    it("should display AP icons based on speed", async () => {
      // Speed = 8, so AP = 3 + floor(8/5) = 3 + 1 = 4
      testUnit.baseStats.speed = 8;
      testUnit.currentAP = 3;
      element.unit = testUnit;
      await waitForUpdate();

      // Find the AP stat item (which shows AP icons)
      const apStat = Array.from(queryShadowAll(".stat-item")).find((item) =>
        item.textContent.includes("AP")
      );
      expect(apStat).to.exist;

      const apIcons = apStat.querySelectorAll(".ap-icon");
      expect(apIcons.length).to.equal(4); // Max AP

      const emptyIcons = apStat.querySelectorAll(".ap-icon.empty");
      expect(emptyIcons.length).to.equal(1); // One empty (4 total - 3 used)
    });
  });

  describe("CoA 2: Equipment Swapping", () => {
    it("should show equipment slots in paper doll", async () => {
      element.unit = testUnit;
      await waitForUpdate();

      // Use the new class names (mainHand, offHand, body, accessory)
      const weaponSlot = queryShadow(".equipment-slot.mainHand");
      const armorSlot = queryShadow(".equipment-slot.body");
      const relicSlot = queryShadow(".equipment-slot.accessory");
      const utilitySlot = queryShadow(".equipment-slot.offHand");

      expect(weaponSlot).to.exist;
      expect(armorSlot).to.exist;
      expect(relicSlot).to.exist;
      expect(utilitySlot).to.exist;
    });

    it("should show ghost icon for empty slots", async () => {
      element.unit = testUnit;
      await waitForUpdate();

      const weaponSlot = queryShadow(".equipment-slot.mainHand");
      const slotIcon = weaponSlot.querySelector(".slot-icon");
      expect(slotIcon).to.exist;
    });

    it("should show item icon for equipped items", async () => {
      // Use the new loadout system
      testUnit.loadout.mainHand = {
        uid: "ITEM_TEST_SWORD_1",
        defId: "ITEM_TEST_SWORD",
        isNew: false,
        quantity: 1,
      };
      
      // Mock inventoryManager with item registry
      const mockItemRegistry = new Map();
      mockItemRegistry.set("ITEM_TEST_SWORD", {
        id: "ITEM_TEST_SWORD",
        name: "Test Sword",
        type: "WEAPON",
        icon: "⚔️",
      });
      
      element.unit = testUnit;
      element.inventoryManager = {
        itemRegistry: mockItemRegistry,
      };
      await waitForUpdate();

      const weaponSlot = queryShadow(".equipment-slot.mainHand");
      const itemIcon = weaponSlot.querySelector(".item-icon");
      expect(itemIcon).to.exist;
    });

    it("should switch to inventory tab when slot is clicked", async () => {
      element.unit = testUnit;
      element.inventory = [];
      await waitForUpdate();

      const weaponSlot = queryShadow(".equipment-slot.mainHand");
      weaponSlot.click();
      await waitForUpdate();

      expect(element.activeTab).to.equal("INVENTORY");
      expect(element.selectedSlot).to.equal("MAIN_HAND");
    });

    it("should filter inventory by slot type when slot is selected", async () => {
      const weapon1 = new Item({
        id: "ITEM_SWORD",
        name: "Sword",
        type: "WEAPON",
      });
      const weapon2 = new Item({
        id: "ITEM_AXE",
        name: "Axe",
        type: "WEAPON",
      });
      const armor = new Item({
        id: "ITEM_PLATE",
        name: "Plate",
        type: "ARMOR",
      });

      element.unit = testUnit;
      element.inventory = [weapon1, weapon2, armor];
      element.selectedSlot = "WEAPON";
      await waitForUpdate();

      const itemCards = queryShadowAll(".item-card");
      expect(itemCards.length).to.equal(2); // Only weapons
    });

    it("should equip item when clicked in inventory", async () => {
      const weapon = new Item({
        id: "ITEM_SWORD",
        name: "Sword",
        type: "WEAPON",
        stats: { attack: 10 },
      });
      const oldWeapon = new Item({
        id: "ITEM_OLD_SWORD",
        name: "Old Sword",
        type: "WEAPON",
      });

      testUnit.equipment.weapon = oldWeapon;
      element.unit = testUnit;
      element.inventory = [weapon];
      element.selectedSlot = "WEAPON";

      let equipEventFired = false;
      let equipEventDetail = null;
      element.addEventListener("equip-item", (e) => {
        equipEventFired = true;
        equipEventDetail = e.detail;
      });

      await waitForUpdate();

      const itemCard = queryShadow(".item-card");
      itemCard.click();
      await waitForUpdate();

      expect(equipEventFired).to.be.true;
      expect(equipEventDetail.unitId).to.equal(testUnit.id);
      expect(equipEventDetail.slot).to.equal("WEAPON");
      expect(equipEventDetail.item.id).to.equal("ITEM_SWORD");
      expect(equipEventDetail.oldItem.id).to.equal("ITEM_OLD_SWORD");

      // Old item should be in inventory
      expect(element.inventory.some((item) => item.id === "ITEM_OLD_SWORD")).to.be
        .true;
      // New item should be equipped
      expect(testUnit.equipment.weapon.id).to.equal("ITEM_SWORD");
    });

    it("should update stats immediately after equipping", async () => {
      const weapon = new Item({
        id: "ITEM_SWORD",
        name: "Sword",
        type: "WEAPON",
        stats: { attack: 15 },
      });

      element.unit = testUnit;
      element.inventory = [weapon];
      element.selectedSlot = "WEAPON";
      await waitForUpdate();

      const initialAttack = Array.from(queryShadowAll(".stat-item")).find((item) =>
        item.textContent.includes("Attack")
      );
      const initialValue = parseInt(
        initialAttack.querySelector(".stat-value").textContent.trim()
      );

      const itemCard = queryShadow(".item-card");
      itemCard.click();
      await waitForUpdate();

      const updatedAttack = Array.from(queryShadowAll(".stat-item")).find((item) =>
        item.textContent.includes("Attack")
      );
      const updatedValue = parseInt(
        updatedAttack.querySelector(".stat-value").textContent.trim()
      );

      expect(updatedValue).to.equal(initialValue + 15);
    });

    it("should not allow equipping in read-only mode", async () => {
      element.unit = testUnit;
      element.readOnly = true;
      element.inventory = [
        new Item({
          id: "ITEM_SWORD",
          name: "Sword",
          type: "WEAPON",
        }),
      ];
      element.selectedSlot = "MAIN_HAND";
      await waitForUpdate();

      const weaponSlot = queryShadow(".equipment-slot.mainHand");
      expect(weaponSlot.hasAttribute("disabled")).to.be.true;

      const itemCard = queryShadow(".item-card");
      const initialWeapon = testUnit.equipment.weapon;
      itemCard.click();
      await waitForUpdate();

      // Equipment should not have changed
      expect(testUnit.equipment.weapon).to.equal(initialWeapon);
    });
  });

  describe("CoA 3: Skill Interaction", () => {
    it("should display skill tree tab", async () => {
      element.unit = testUnit;
      element.activeTab = "SKILLS";
      await waitForUpdate();

      const skillsTab = Array.from(queryShadowAll(".tab-button")).find((btn) =>
        btn.textContent.includes("Skills")
      );
      expect(skillsTab).to.exist;

      const skillsContainer = queryShadow(".skills-container");
      expect(skillsContainer).to.exist;
    });

    it("should embed skill-tree-ui component", async () => {
      element.unit = testUnit;
      element.activeTab = "SKILLS";
      await waitForUpdate();

      const skillTree = queryShadow("skill-tree-ui");
      expect(skillTree).to.exist;
      expect(skillTree.unit).to.equal(testUnit);
    });

    it("should display SP badge when skill points are available", async () => {
      testUnit.classMastery["CLASS_VANGUARD"].skillPoints = 3;
      element.unit = testUnit;
      await waitForUpdate();

      const spBadge = queryShadow(".sp-badge");
      expect(spBadge).to.exist;
      expect(spBadge.textContent).to.include("SP: 3");
    });

    it("should not display SP badge when no skill points", async () => {
      testUnit.classMastery["CLASS_VANGUARD"].skillPoints = 0;
      element.unit = testUnit;
      await waitForUpdate();

      const spBadge = queryShadow(".sp-badge");
      expect(spBadge).to.be.null;
    });

    it("should handle unlock-request and update unit stats", async () => {
      // Set up unit with skill points and mock recalculateStats
      testUnit.classMastery["CLASS_VANGUARD"].skillPoints = 2;
      testUnit.classMastery["CLASS_VANGUARD"].unlockedNodes = [];
      testUnit.maxHealth = 100;
      testUnit.currentHealth = 100;

      let recalculateStatsCalled = false;
      let recalculateStatsArgs = null;
      testUnit.recalculateStats = (itemRegistry, treeDef) => {
        recalculateStatsCalled = true;
        recalculateStatsArgs = { itemRegistry, treeDef };
        // Simulate stat boost application
        testUnit.maxHealth = 110; // Base 100 + 10 from health boost
      };

      element.unit = testUnit;
      element.activeTab = "SKILLS";
      await waitForUpdate();

      // Create mock tree definition
      const mockTreeDef = {
        id: "TREE_TEST",
        nodes: {
          ROOT: {
            id: "ROOT",
            tier: 1,
            type: "STAT_BOOST",
            data: { stat: "health", value: 10 },
            req: 1,
            cost: 1,
          },
        },
      };
      element.treeDef = mockTreeDef;
      await waitForUpdate();

      // Call the handler directly (since it's a private method, we'll simulate the event)
      const unlockEvent = new CustomEvent("unlock-request", {
        detail: { nodeId: "ROOT", cost: 1 },
        bubbles: true,
        composed: true,
      });
      // Simulate the event being handled by calling the method directly
      element._handleUnlockRequest(unlockEvent);
      await waitForUpdate();

      // Verify node was unlocked
      expect(testUnit.classMastery["CLASS_VANGUARD"].unlockedNodes).to.include("ROOT");
      expect(testUnit.classMastery["CLASS_VANGUARD"].skillPoints).to.equal(1);

      // Verify recalculateStats was called with correct args
      expect(recalculateStatsCalled).to.be.true;
      expect(recalculateStatsArgs.treeDef).to.exist;
    });

    it("should dispatch skill-unlocked event after unlocking", async () => {
      testUnit.classMastery["CLASS_VANGUARD"].skillPoints = 2;
      testUnit.classMastery["CLASS_VANGUARD"].unlockedNodes = [];
      testUnit.recalculateStats = () => {}; // Mock function

      element.unit = testUnit;
      await waitForUpdate();

      let skillUnlockedEventFired = false;
      let skillUnlockedEventDetail = null;
      element.addEventListener("skill-unlocked", (e) => {
        skillUnlockedEventFired = true;
        skillUnlockedEventDetail = e.detail;
      });

      const unlockEvent = new CustomEvent("unlock-request", {
        detail: { nodeId: "ROOT", cost: 1 },
        bubbles: true,
        composed: true,
      });
      // Call the handler directly
      element._handleUnlockRequest(unlockEvent);
      await waitForUpdate();

      expect(skillUnlockedEventFired).to.be.true;
      expect(skillUnlockedEventDetail.unitId).to.equal(testUnit.id);
      expect(skillUnlockedEventDetail.nodeId).to.equal("ROOT");
      expect(skillUnlockedEventDetail.cost).to.equal(1);
    });

    it("should update SkillTreeUI after unlocking", async () => {
      testUnit.classMastery["CLASS_VANGUARD"].skillPoints = 2;
      testUnit.classMastery["CLASS_VANGUARD"].unlockedNodes = [];
      testUnit.recalculateStats = () => {}; // Mock function

      element.unit = testUnit;
      element.activeTab = "SKILLS";
      await waitForUpdate();

      const skillTree = queryShadow("skill-tree-ui");
      expect(skillTree).to.exist;

      const initialUpdateTrigger = skillTree.updateTrigger || 0;

      const unlockEvent = new CustomEvent("unlock-request", {
        detail: { nodeId: "ROOT", cost: 1 },
        bubbles: true,
        composed: true,
      });
      // Call the handler directly
      element._handleUnlockRequest(unlockEvent);

      // Wait for setTimeout to execute
      await new Promise((resolve) => setTimeout(resolve, 20));
      await waitForUpdate();

      // Verify updateTrigger was incremented
      expect(skillTree.updateTrigger).to.be.greaterThan(initialUpdateTrigger);
    });

    it("should include skill tree stat boosts in stat breakdown", async () => {
      testUnit.classMastery["CLASS_VANGUARD"].unlockedNodes = ["ROOT"];
      testUnit.baseStats.health = 100;
      testUnit.maxHealth = 100;

      // Create mock tree definition with health boost
      const mockTreeDef = {
        id: "TREE_TEST",
        nodes: {
          ROOT: {
            id: "ROOT",
            tier: 1,
            type: "STAT_BOOST",
            data: { stat: "health", value: 10 },
            req: 1,
            cost: 1,
          },
        },
      };

      element.unit = testUnit;
      element.treeDef = mockTreeDef;
      await waitForUpdate();

      // Get health stat breakdown - health uses a health bar, not stat-value
      const healthStat = Array.from(queryShadowAll(".stat-item")).find((item) =>
        item.textContent.includes("Health")
      );
      expect(healthStat).to.exist;

      // Health shows as "current / max" in the health label
      const healthLabel = healthStat.querySelector(".health-label");
      if (healthLabel) {
        // Health bar shows current/max, so we check the max value
        const healthText = healthLabel.textContent;
        const match = healthText.match(/\/(\d+)/);
        if (match) {
          const maxHealth = parseInt(match[1]);
          // Should be 100 base + 10 boost = 110
          expect(maxHealth).to.equal(110);
        }
      } else {
        // Fallback: check if the breakdown tooltip would show the boost
        // This test verifies the calculation happens, even if we can't easily test the UI
        const { total } = element._getEffectiveStat("health");
        expect(total).to.equal(110);
      }
    });

    describe("30-Node Skill Tree Integration", () => {
      it("should receive and pass full 30-node tree to SkillTreeUI", async () => {
        // Create a mock 30-node tree (simplified version)
        const mock30NodeTree = {
          id: "TREE_CLASS_VANGUARD",
          nodes: {},
        };

        // Generate 30 node IDs
        for (let i = 1; i <= 30; i++) {
          mock30NodeTree.nodes[`NODE_${i}`] = {
            id: `NODE_${i}`,
            tier: Math.ceil(i / 6),
            type: i % 3 === 0 ? "STAT_BOOST" : "ACTIVE_SKILL",
            data: i % 3 === 0 
              ? { stat: "health", value: i } 
              : { id: `SKILL_${i}`, name: `Skill ${i}` },
            req: Math.ceil(i / 6),
            cost: Math.ceil(i / 10),
            children: i < 30 ? [`NODE_${i + 1}`] : [],
          };
        }

        element.unit = testUnit;
        element.treeDef = mock30NodeTree;
        element.activeTab = "SKILLS";
        await waitForUpdate();

        const skillTree = queryShadow("skill-tree-ui");
        expect(skillTree).to.exist;
        expect(skillTree.treeDef).to.exist;
        expect(skillTree.treeDef.id).to.equal("TREE_CLASS_VANGUARD");
        expect(Object.keys(skillTree.treeDef.nodes)).to.have.length(30);
      });

      it("should handle treeDef with all node types from template", async () => {
        const mockFullTree = {
          id: "TREE_TEST",
          nodes: {
            NODE_T1_1: {
              tier: 1,
              type: "STAT_BOOST",
              data: { stat: "health", value: 2 },
              req: 1,
              cost: 1,
              children: ["NODE_T2_1", "NODE_T2_2"],
            },
            NODE_T2_1: {
              tier: 2,
              type: "STAT_BOOST",
              data: { stat: "defense", value: 2 },
              req: 2,
              cost: 1,
              children: ["NODE_T3_1"],
            },
            NODE_T2_2: {
              tier: 2,
              type: "ACTIVE_SKILL",
              data: { id: "SKILL_1", name: "Shield Bash" },
              req: 2,
              cost: 1,
              children: ["NODE_T3_2"],
            },
            NODE_T3_1: {
              tier: 3,
              type: "STAT_BOOST",
              data: { stat: "health", value: 6 },
              req: 3,
              cost: 1,
              children: [],
            },
            NODE_T3_2: {
              tier: 3,
              type: "ACTIVE_SKILL",
              data: { id: "SKILL_2", name: "Taunt" },
              req: 3,
              cost: 1,
              children: [],
            },
            NODE_T4_1: {
              tier: 4,
              type: "ACTIVE_SKILL",
              data: { id: "SKILL_3", name: "Skill 3" },
              req: 4,
              cost: 2,
              children: [],
            },
            NODE_T4_2: {
              tier: 4,
              type: "PASSIVE_ABILITY",
              data: { effect_id: "PASSIVE_1", name: "Passive 1" },
              req: 4,
              cost: 2,
              children: [],
            },
          },
        };

        element.unit = testUnit;
        element.treeDef = mockFullTree;
        element.activeTab = "SKILLS";
        await waitForUpdate();

        const skillTree = queryShadow("skill-tree-ui");
        expect(skillTree).to.exist;
        expect(skillTree.treeDef).to.equal(mockFullTree);
        
        // Verify all node types are present
        const nodes = skillTree.treeDef.nodes;
        expect(nodes.NODE_T1_1.type).to.equal("STAT_BOOST");
        expect(nodes.NODE_T2_2.type).to.equal("ACTIVE_SKILL");
        expect(nodes.NODE_T4_2.type).to.equal("PASSIVE_ABILITY");
      });

      it("should use treeDef in _getTreeDefinition method", async () => {
        const mockTree = {
          id: "TREE_TEST",
          nodes: {
            NODE_1: {
              tier: 1,
              type: "STAT_BOOST",
              data: { stat: "health", value: 2 },
              req: 1,
              cost: 1,
              children: [],
            },
          },
        };

        element.unit = testUnit;
        element.treeDef = mockTree;
        await waitForUpdate();

        const treeDef = element._getTreeDefinition();
        expect(treeDef).to.equal(mockTree);
        expect(treeDef.id).to.equal("TREE_TEST");
      });

      it("should pass treeDef to recalculateStats when unlocking nodes", async () => {
        testUnit.classMastery["CLASS_VANGUARD"].skillPoints = 2;
        testUnit.classMastery["CLASS_VANGUARD"].unlockedNodes = [];
        testUnit.recalculateStats = () => {}; // Mock function

        const mockTree = {
          id: "TREE_TEST",
          nodes: {
            NODE_1: {
              tier: 1,
              type: "STAT_BOOST",
              data: { stat: "health", value: 10 },
              req: 1,
              cost: 1,
              children: [],
            },
          },
        };

        let recalculateStatsCalledWith = null;
        testUnit.recalculateStats = (itemRegistry, treeDef) => {
          recalculateStatsCalledWith = { itemRegistry, treeDef };
        };

        element.unit = testUnit;
        element.treeDef = mockTree;
        await waitForUpdate();

        const unlockEvent = new CustomEvent("unlock-request", {
          detail: { nodeId: "NODE_1", cost: 1 },
          bubbles: true,
          composed: true,
        });
        element._handleUnlockRequest(unlockEvent);
        await waitForUpdate();

        expect(recalculateStatsCalledWith).to.exist;
        expect(recalculateStatsCalledWith.treeDef).to.equal(mockTree);
      });
    });
  });

  describe("CoA 4: Context Awareness", () => {
    it("should display inventory tab", async () => {
      element.unit = testUnit;
      element.inventory = [];
      element.activeTab = "INVENTORY";
      await waitForUpdate();

      const inventoryGrid = queryShadow(".inventory-grid");
      expect(inventoryGrid).to.exist;
    });

    it("should show empty message when inventory is empty", async () => {
      element.unit = testUnit;
      element.inventory = [];
      element.activeTab = "INVENTORY";
      await waitForUpdate();

      const emptyMessage = queryShadow(".inventory-grid p");
      expect(emptyMessage).to.exist;
      expect(emptyMessage.textContent).to.include("No items available");
    });

    it("should display mastery tab", async () => {
      element.unit = testUnit;
      element.activeTab = "MASTERY";
      await waitForUpdate();

      const masteryContainer = queryShadow(".mastery-container");
      expect(masteryContainer).to.exist;
    });

    it("should show mastery progress for all classes", async () => {
      testUnit.classMastery["CLASS_VANGUARD"] = {
        level: 5,
        xp: 250,
        skillPoints: 2,
        unlockedNodes: [],
      };
      testUnit.classMastery["CLASS_WEAVER"] = {
        level: 2,
        xp: 50,
        skillPoints: 0,
        unlockedNodes: [],
      };

      element.unit = testUnit;
      element.activeTab = "MASTERY";
      await waitForUpdate();

      const masteryClasses = queryShadowAll(".mastery-class");
      expect(masteryClasses.length).to.equal(2);
    });
  });

  describe("Header Rendering", () => {
    it("should display unit name, class, and level", async () => {
      element.unit = testUnit;
      await waitForUpdate();

      const name = queryShadow(".name");
      expect(name.textContent).to.include("Test Vanguard");

      const classTitle = queryShadow(".class-title");
      expect(classTitle.textContent).to.include("Vanguard");

      const level = queryShadow(".level");
      expect(level.textContent).to.include("Level 5");
    });

    it("should display XP bar", async () => {
      element.unit = testUnit;
      await waitForUpdate();

      const xpBar = queryShadow(".xp-bar-container");
      expect(xpBar).to.exist;

      const xpLabel = queryShadow(".xp-label");
      expect(xpLabel.textContent).to.include("250");
    });

    it("should display close button", async () => {
      element.unit = testUnit;
      await waitForUpdate();

      const closeButton = queryShadow(".close-button");
      expect(closeButton).to.exist;
    });

    it("should dispatch close event when close button is clicked", async () => {
      element.unit = testUnit;
      await waitForUpdate();

      let closeEventFired = false;
      element.addEventListener("close", () => {
        closeEventFired = true;
      });

      const closeButton = queryShadow(".close-button");
      closeButton.click();

      expect(closeEventFired).to.be.true;
    });
  });

  describe("Tab Switching", () => {
    it("should switch between tabs", async () => {
      element.unit = testUnit;
      await waitForUpdate();

      const inventoryTab = queryShadowAll(".tab-button")[0];
      const skillsTab = queryShadowAll(".tab-button")[1];
      const masteryTab = queryShadowAll(".tab-button")[2];

      expect(inventoryTab.classList.contains("active")).to.be.true;

      skillsTab.click();
      await waitForUpdate();

      expect(element.activeTab).to.equal("SKILLS");
      expect(skillsTab.classList.contains("active")).to.be.true;

      masteryTab.click();
      await waitForUpdate();

      expect(element.activeTab).to.equal("MASTERY");
      expect(masteryTab.classList.contains("active")).to.be.true;
    });
  });
});

