import { expect } from "@esm-bundle/chai";
import { SkillTreeFactory } from "../../src/factories/SkillTreeFactory.js";

describe("System: Skill Tree Factory", () => {
  let factory;
  let mockTemplates;
  let mockSkills;
  let mockClassConfig;

  beforeEach(() => {
    // 1. Setup Mock Data
    mockTemplates = {
      TEMPLATE_STANDARD_30: {
        nodes: {
          ROOT_NODE: {
            tier: 1,
            type: "SLOT_STAT_PRIMARY",
            children: ["CHILD_NODE"],
          },
          CHILD_NODE: { tier: 1, type: "SLOT_SKILL_ACTIVE_1", children: [] },
        },
      },
    };

    mockSkills = {
      SKILL_FIREBALL: { id: "SKILL_FIREBALL", name: "Fireball", damage: 10 },
    };

    mockClassConfig = {
      id: "TEST_CLASS",
      skillTreeData: {
        primary_stat: "attack",
        secondary_stat: "defense",
        active_skills: ["SKILL_FIREBALL"],
        passive_skills: ["PASSIVE_BURNING"],
      },
    };

    // 2. Initialize Factory
    factory = new SkillTreeFactory(mockTemplates, mockSkills);
  });

  it("CoA 1: Should maintain the topology (structure) of the template", () => {
    const tree = factory.createTree(mockClassConfig);

    expect(tree.nodes).to.have.property("ROOT_NODE");
    expect(tree.nodes).to.have.property("CHILD_NODE");
    expect(tree.nodes["ROOT_NODE"].children).to.include("CHILD_NODE");
  });

  it("CoA 2: Should inject Primary Stats based on Class Config", () => {
    const tree = factory.createTree(mockClassConfig);
    const rootNode = tree.nodes["ROOT_NODE"];

    expect(rootNode.type).to.equal("STAT_BOOST");
    expect(rootNode.data.stat).to.equal("attack"); // Injected from config
    expect(rootNode.data.value).to.equal(2); // Tier 1 * 2
  });

  it("CoA 3: Should inject Active Skills based on Class Config", () => {
    const tree = factory.createTree(mockClassConfig);
    const childNode = tree.nodes["CHILD_NODE"];

    expect(childNode.type).to.equal("ACTIVE_SKILL");
    // Should resolve the full skill object from registry
    expect(childNode.data.name).to.equal("Fireball");
  });

  describe("30-Node Template Support", () => {
    let fullTemplate;
    let fullClassConfig;
    let fullSkills;

    beforeEach(() => {
      // Create a mock 30-node template
      fullTemplate = {
        TEMPLATE_STANDARD_30: {
          nodes: {
            NODE_T1_1: {
              tier: 1,
              type: "SLOT_STAT_PRIMARY",
              children: ["NODE_T2_1", "NODE_T2_2"],
              req: 1,
              cost: 1,
            },
            NODE_T2_1: {
              tier: 2,
              type: "SLOT_STAT_SECONDARY",
              children: ["NODE_T3_1"],
              req: 2,
              cost: 1,
            },
            NODE_T2_2: {
              tier: 2,
              type: "SLOT_SKILL_ACTIVE_1",
              children: ["NODE_T3_2"],
              req: 2,
              cost: 1,
            },
            NODE_T3_1: {
              tier: 3,
              type: "SLOT_STAT_PRIMARY",
              children: [],
              req: 3,
              cost: 1,
            },
            NODE_T3_2: {
              tier: 3,
              type: "SLOT_SKILL_ACTIVE_2",
              children: [],
              req: 3,
              cost: 1,
            },
          },
        },
      };

      fullClassConfig = {
        id: "CLASS_VANGUARD",
        skillTreeData: {
          primary_stat: "health",
          secondary_stat: "defense",
          active_skills: ["SKILL_SHIELD_BASH", "SKILL_TAUNT"],
          passive_skills: ["PASSIVE_IRON_SKIN", "PASSIVE_THORNS"],
        },
      };

      fullSkills = {
        SKILL_SHIELD_BASH: { id: "SKILL_SHIELD_BASH", name: "Shield Bash" },
        SKILL_TAUNT: { id: "SKILL_TAUNT", name: "Taunt" },
      };
    });

    it("should generate tree with all nodes from template", () => {
      const fullFactory = new SkillTreeFactory(fullTemplate, fullSkills);
      const tree = fullFactory.createTree(fullClassConfig);

      // Should have all 5 nodes from template
      expect(Object.keys(tree.nodes)).to.have.length(5);
      expect(tree.nodes).to.have.property("NODE_T1_1");
      expect(tree.nodes).to.have.property("NODE_T2_1");
      expect(tree.nodes).to.have.property("NODE_T2_2");
      expect(tree.nodes).to.have.property("NODE_T3_1");
      expect(tree.nodes).to.have.property("NODE_T3_2");
    });

    it("should hydrate all stat boost nodes correctly", () => {
      const fullFactory = new SkillTreeFactory(fullTemplate, fullSkills);
      const tree = fullFactory.createTree(fullClassConfig);

      // Tier 1 primary stat (health) - should be tier * 2 = 2
      const t1Node = tree.nodes["NODE_T1_1"];
      expect(t1Node.type).to.equal("STAT_BOOST");
      expect(t1Node.data.stat).to.equal("health");
      expect(t1Node.data.value).to.equal(2); // Tier 1 * 2

      // Tier 2 secondary stat (defense) - should be tier = 2
      const t2Node = tree.nodes["NODE_T2_1"];
      expect(t2Node.type).to.equal("STAT_BOOST");
      expect(t2Node.data.stat).to.equal("defense");
      expect(t2Node.data.value).to.equal(2); // Tier 2

      // Tier 3 primary stat (health) - should be tier * 2 = 6
      const t3Node = tree.nodes["NODE_T3_1"];
      expect(t3Node.type).to.equal("STAT_BOOST");
      expect(t3Node.data.stat).to.equal("health");
      expect(t3Node.data.value).to.equal(6); // Tier 3 * 2
    });

    it("should hydrate all active skill nodes correctly", () => {
      const fullFactory = new SkillTreeFactory(fullTemplate, fullSkills);
      const tree = fullFactory.createTree(fullClassConfig);

      // ACTIVE_1 should map to first skill
      const active1Node = tree.nodes["NODE_T2_2"];
      expect(active1Node.type).to.equal("ACTIVE_SKILL");
      expect(active1Node.data.name).to.equal("Shield Bash");

      // ACTIVE_2 should map to second skill
      const active2Node = tree.nodes["NODE_T3_2"];
      expect(active2Node.type).to.equal("ACTIVE_SKILL");
      expect(active2Node.data.name).to.equal("Taunt");
    });

    it("should handle missing skills gracefully", () => {
      const classConfigMissingSkills = {
        id: "TEST_CLASS",
        skillTreeData: {
          primary_stat: "attack",
          secondary_stat: "defense",
          active_skills: ["SKILL_EXISTS"], // Only one skill
          passive_skills: [],
        },
      };

      const skills = {
        SKILL_EXISTS: { id: "SKILL_EXISTS", name: "Existing Skill" },
      };

      const fullFactory = new SkillTreeFactory(fullTemplate, skills);
      const tree = fullFactory.createTree(classConfigMissingSkills);

      // ACTIVE_1 should work
      const active1Node = tree.nodes["NODE_T2_2"];
      expect(active1Node.data.name).to.equal("Existing Skill");

      // ACTIVE_2 should fallback to "Unknown Skill"
      const active2Node = tree.nodes["NODE_T3_2"];
      expect(active2Node.data.name).to.equal("Unknown Skill");
    });
  });

  describe("Extended Skill Slots", () => {
    let extendedTemplate;
    let extendedClassConfig;
    let extendedSkills;

    beforeEach(() => {
      extendedTemplate = {
        TEMPLATE_STANDARD_30: {
          nodes: {
            ACTIVE_1: {
              tier: 2,
              type: "SLOT_SKILL_ACTIVE_1",
              children: [],
              req: 2,
              cost: 1,
            },
            ACTIVE_2: {
              tier: 2,
              type: "SLOT_SKILL_ACTIVE_2",
              children: [],
              req: 2,
              cost: 1,
            },
            ACTIVE_3: {
              tier: 3,
              type: "SLOT_SKILL_ACTIVE_3",
              children: [],
              req: 3,
              cost: 1,
            },
            ACTIVE_4: {
              tier: 3,
              type: "SLOT_SKILL_ACTIVE_4",
              children: [],
              req: 3,
              cost: 1,
            },
            PASSIVE_1: {
              tier: 2,
              type: "SLOT_SKILL_PASSIVE_1",
              children: [],
              req: 2,
              cost: 2,
            },
            PASSIVE_2: {
              tier: 3,
              type: "SLOT_SKILL_PASSIVE_2",
              children: [],
              req: 3,
              cost: 2,
            },
            PASSIVE_3: {
              tier: 4,
              type: "SLOT_SKILL_PASSIVE_3",
              children: [],
              req: 4,
              cost: 2,
            },
            PASSIVE_4: {
              tier: 4,
              type: "SLOT_SKILL_PASSIVE_4",
              children: [],
              req: 4,
              cost: 2,
            },
          },
        },
      };

      extendedClassConfig = {
        id: "TEST_CLASS",
        skillTreeData: {
          primary_stat: "attack",
          secondary_stat: "defense",
          active_skills: [
            "SKILL_1",
            "SKILL_2",
            "SKILL_3",
            "SKILL_4",
          ],
          passive_skills: [
            "PASSIVE_1",
            "PASSIVE_2",
            "PASSIVE_3",
            "PASSIVE_4",
          ],
        },
      };

      extendedSkills = {
        SKILL_1: { id: "SKILL_1", name: "Skill 1" },
        SKILL_2: { id: "SKILL_2", name: "Skill 2" },
        SKILL_3: { id: "SKILL_3", name: "Skill 3" },
        SKILL_4: { id: "SKILL_4", name: "Skill 4" },
      };
    });

    it("should hydrate ACTIVE_3 and ACTIVE_4 slots", () => {
      const extendedFactory = new SkillTreeFactory(
        extendedTemplate,
        extendedSkills
      );
      const tree = extendedFactory.createTree(extendedClassConfig);

      const active3Node = tree.nodes["ACTIVE_3"];
      expect(active3Node.type).to.equal("ACTIVE_SKILL");
      expect(active3Node.data.name).to.equal("Skill 3");

      const active4Node = tree.nodes["ACTIVE_4"];
      expect(active4Node.type).to.equal("ACTIVE_SKILL");
      expect(active4Node.data.name).to.equal("Skill 4");
    });

    it("should hydrate PASSIVE_2, PASSIVE_3, and PASSIVE_4 slots", () => {
      const extendedFactory = new SkillTreeFactory(
        extendedTemplate,
        extendedSkills
      );
      const tree = extendedFactory.createTree(extendedClassConfig);

      const passive2Node = tree.nodes["PASSIVE_2"];
      expect(passive2Node.type).to.equal("PASSIVE_ABILITY");
      expect(passive2Node.data.name).to.equal("PASSIVE_2");
      expect(passive2Node.data.effect_id).to.equal("PASSIVE_2");

      const passive3Node = tree.nodes["PASSIVE_3"];
      expect(passive3Node.type).to.equal("PASSIVE_ABILITY");
      expect(passive3Node.data.name).to.equal("PASSIVE_3");

      const passive4Node = tree.nodes["PASSIVE_4"];
      expect(passive4Node.type).to.equal("PASSIVE_ABILITY");
      expect(passive4Node.data.name).to.equal("PASSIVE_4");
    });

    it("should handle missing extended skills with fallbacks", () => {
      const limitedClassConfig = {
        id: "TEST_CLASS",
        skillTreeData: {
          primary_stat: "attack",
          secondary_stat: "defense",
          active_skills: ["SKILL_1"], // Only one skill
          passive_skills: ["PASSIVE_1"], // Only one passive
        },
      };

      const limitedFactory = new SkillTreeFactory(
        extendedTemplate,
        extendedSkills
      );
      const tree = limitedFactory.createTree(limitedClassConfig);

      // ACTIVE_3 should fallback
      const active3Node = tree.nodes["ACTIVE_3"];
      expect(active3Node.data.name).to.equal("Unknown Skill");

      // PASSIVE_3 should fallback
      const passive3Node = tree.nodes["PASSIVE_3"];
      expect(passive3Node.data.name).to.equal("Unknown Passive");
    });
  });

  describe("Full 30-Node Template Generation", () => {
    let full30NodeTemplate;
    let fullClassConfig;
    let fullSkills;

    beforeEach(() => {
      // Create a simplified but representative 30-node template structure
      // This mirrors the actual template_standard_30.json structure
      full30NodeTemplate = {
        TEMPLATE_STANDARD_30: {
          nodes: {
            // Tier 1: 1 node
            NODE_T1_1: {
              tier: 1,
              type: "SLOT_STAT_PRIMARY",
              children: ["NODE_T2_1", "NODE_T2_2", "NODE_T2_3"],
              req: 1,
              cost: 1,
            },
            // Tier 2: 3 nodes
            NODE_T2_1: {
              tier: 2,
              type: "SLOT_STAT_SECONDARY",
              children: ["NODE_T3_1", "NODE_T3_2"],
              req: 2,
              cost: 1,
            },
            NODE_T2_2: {
              tier: 2,
              type: "SLOT_SKILL_ACTIVE_1",
              children: ["NODE_T3_3", "NODE_T3_4"],
              req: 2,
              cost: 1,
            },
            NODE_T2_3: {
              tier: 2,
              type: "SLOT_STAT_PRIMARY",
              children: ["NODE_T3_5", "NODE_T3_6"],
              req: 2,
              cost: 1,
            },
            // Tier 3: 6 nodes
            NODE_T3_1: {
              tier: 3,
              type: "SLOT_STAT_PRIMARY",
              children: ["NODE_T4_1", "NODE_T4_2"],
              req: 3,
              cost: 1,
            },
            NODE_T3_2: {
              tier: 3,
              type: "SLOT_STAT_SECONDARY",
              children: ["NODE_T4_3"],
              req: 3,
              cost: 1,
            },
            NODE_T3_3: {
              tier: 3,
              type: "SLOT_SKILL_ACTIVE_2",
              children: ["NODE_T4_4", "NODE_T4_5"],
              req: 3,
              cost: 1,
            },
            NODE_T3_4: {
              tier: 3,
              type: "SLOT_SKILL_PASSIVE_1",
              children: ["NODE_T4_6"],
              req: 3,
              cost: 2,
            },
            NODE_T3_5: {
              tier: 3,
              type: "SLOT_STAT_SECONDARY",
              children: ["NODE_T4_7"],
              req: 3,
              cost: 1,
            },
            NODE_T3_6: {
              tier: 3,
              type: "SLOT_SKILL_ACTIVE_1",
              children: ["NODE_T4_8", "NODE_T4_9"],
              req: 3,
              cost: 1,
            },
            // Tier 4: 9 nodes
            NODE_T4_1: {
              tier: 4,
              type: "SLOT_STAT_PRIMARY",
              children: ["NODE_T5_1", "NODE_T5_2"],
              req: 4,
              cost: 2,
            },
            NODE_T4_2: {
              tier: 4,
              type: "SLOT_STAT_SECONDARY",
              children: ["NODE_T5_3"],
              req: 4,
              cost: 2,
            },
            NODE_T4_3: {
              tier: 4,
              type: "SLOT_STAT_PRIMARY",
              children: ["NODE_T5_4"],
              req: 4,
              cost: 2,
            },
            NODE_T4_4: {
              tier: 4,
              type: "SLOT_SKILL_ACTIVE_3",
              children: ["NODE_T5_5", "NODE_T5_6"],
              req: 4,
              cost: 2,
            },
            NODE_T4_5: {
              tier: 4,
              type: "SLOT_SKILL_ACTIVE_4",
              children: ["NODE_T5_7"],
              req: 4,
              cost: 2,
            },
            NODE_T4_6: {
              tier: 4,
              type: "SLOT_SKILL_PASSIVE_2",
              children: ["NODE_T5_8"],
              req: 4,
              cost: 2,
            },
            NODE_T4_7: {
              tier: 4,
              type: "SLOT_STAT_PRIMARY",
              children: ["NODE_T5_9"],
              req: 4,
              cost: 2,
            },
            NODE_T4_8: {
              tier: 4,
              type: "SLOT_SKILL_PASSIVE_3",
              children: ["NODE_T5_10"],
              req: 4,
              cost: 2,
            },
            NODE_T4_9: {
              tier: 4,
              type: "SLOT_STAT_SECONDARY",
              children: [],
              req: 4,
              cost: 2,
            },
            // Tier 5: 11 nodes (to make 30 total)
            NODE_T5_1: {
              tier: 5,
              type: "SLOT_STAT_PRIMARY",
              children: [],
              req: 5,
              cost: 3,
            },
            NODE_T5_2: {
              tier: 5,
              type: "SLOT_STAT_SECONDARY",
              children: [],
              req: 5,
              cost: 3,
            },
            NODE_T5_3: {
              tier: 5,
              type: "SLOT_STAT_PRIMARY",
              children: [],
              req: 5,
              cost: 3,
            },
            NODE_T5_4: {
              tier: 5,
              type: "SLOT_STAT_SECONDARY",
              children: [],
              req: 5,
              cost: 3,
            },
            NODE_T5_5: {
              tier: 5,
              type: "SLOT_SKILL_ACTIVE_3",
              children: [],
              req: 5,
              cost: 3,
            },
            NODE_T5_6: {
              tier: 5,
              type: "SLOT_SKILL_ACTIVE_4",
              children: [],
              req: 5,
              cost: 3,
            },
            NODE_T5_7: {
              tier: 5,
              type: "SLOT_SKILL_PASSIVE_2",
              children: [],
              req: 5,
              cost: 3,
            },
            NODE_T5_8: {
              tier: 5,
              type: "SLOT_SKILL_PASSIVE_4",
              children: [],
              req: 5,
              cost: 3,
            },
            NODE_T5_9: {
              tier: 5,
              type: "SLOT_STAT_SECONDARY",
              children: [],
              req: 5,
              cost: 3,
            },
            NODE_T5_10: {
              tier: 5,
              type: "SLOT_SKILL_ACTIVE_1",
              children: [],
              req: 5,
              cost: 3,
            },
            NODE_T5_11: {
              tier: 5,
              type: "SLOT_STAT_PRIMARY",
              children: [],
              req: 5,
              cost: 3,
            },
          },
        },
      };

      fullClassConfig = {
        id: "CLASS_VANGUARD",
        skillTreeData: {
          primary_stat: "health",
          secondary_stat: "defense",
          active_skills: [
            "SKILL_SHIELD_BASH",
            "SKILL_TAUNT",
            "SKILL_CHARGE",
            "SKILL_SHIELD_WALL",
          ],
          passive_skills: [
            "PASSIVE_IRON_SKIN",
            "PASSIVE_THORNS",
            "PASSIVE_REGEN",
            "PASSIVE_FORTIFY",
          ],
        },
      };

      fullSkills = {
        SKILL_SHIELD_BASH: { id: "SKILL_SHIELD_BASH", name: "Shield Bash" },
        SKILL_TAUNT: { id: "SKILL_TAUNT", name: "Taunt" },
        SKILL_CHARGE: { id: "SKILL_CHARGE", name: "Charge" },
        SKILL_SHIELD_WALL: { id: "SKILL_SHIELD_WALL", name: "Shield Wall" },
      };
    });

    it("should generate exactly 30 nodes from template", () => {
      const fullFactory = new SkillTreeFactory(full30NodeTemplate, fullSkills);
      const tree = fullFactory.createTree(fullClassConfig);

      expect(Object.keys(tree.nodes)).to.have.length(30);
    });

    it("should maintain all node relationships (children)", () => {
      const fullFactory = new SkillTreeFactory(full30NodeTemplate, fullSkills);
      const tree = fullFactory.createTree(fullClassConfig);

      // Verify root node has 3 children
      expect(tree.nodes.NODE_T1_1.children).to.have.length(3);
      expect(tree.nodes.NODE_T1_1.children).to.include("NODE_T2_1");
      expect(tree.nodes.NODE_T1_1.children).to.include("NODE_T2_2");
      expect(tree.nodes.NODE_T1_1.children).to.include("NODE_T2_3");

      // Verify tier 2 nodes have children
      expect(tree.nodes.NODE_T2_1.children).to.have.length(2);
      expect(tree.nodes.NODE_T2_2.children).to.have.length(2);

      // Verify tier 5 nodes have no children (leaf nodes)
      expect(tree.nodes.NODE_T5_1.children).to.have.length(0);
      expect(tree.nodes.NODE_T5_11.children).to.have.length(0);
    });

    it("should hydrate all stat boost nodes with correct values", () => {
      const fullFactory = new SkillTreeFactory(full30NodeTemplate, fullSkills);
      const tree = fullFactory.createTree(fullClassConfig);

      // Tier 1 primary stat: tier * 2 = 2
      expect(tree.nodes.NODE_T1_1.type).to.equal("STAT_BOOST");
      expect(tree.nodes.NODE_T1_1.data.stat).to.equal("health");
      expect(tree.nodes.NODE_T1_1.data.value).to.equal(2);

      // Tier 2 secondary stat: tier = 2
      expect(tree.nodes.NODE_T2_1.type).to.equal("STAT_BOOST");
      expect(tree.nodes.NODE_T2_1.data.stat).to.equal("defense");
      expect(tree.nodes.NODE_T2_1.data.value).to.equal(2);

      // Tier 5 primary stat: tier * 2 = 10
      expect(tree.nodes.NODE_T5_1.type).to.equal("STAT_BOOST");
      expect(tree.nodes.NODE_T5_1.data.stat).to.equal("health");
      expect(tree.nodes.NODE_T5_1.data.value).to.equal(10);
    });

    it("should hydrate all active skill nodes correctly", () => {
      const fullFactory = new SkillTreeFactory(full30NodeTemplate, fullSkills);
      const tree = fullFactory.createTree(fullClassConfig);

      // ACTIVE_1 should map to first skill
      expect(tree.nodes.NODE_T2_2.type).to.equal("ACTIVE_SKILL");
      expect(tree.nodes.NODE_T2_2.data.name).to.equal("Shield Bash");

      // ACTIVE_2 should map to second skill
      expect(tree.nodes.NODE_T3_3.type).to.equal("ACTIVE_SKILL");
      expect(tree.nodes.NODE_T3_3.data.name).to.equal("Taunt");

      // ACTIVE_3 should map to third skill
      expect(tree.nodes.NODE_T4_4.type).to.equal("ACTIVE_SKILL");
      expect(tree.nodes.NODE_T4_4.data.name).to.equal("Charge");

      // ACTIVE_4 should map to fourth skill
      expect(tree.nodes.NODE_T4_5.type).to.equal("ACTIVE_SKILL");
      expect(tree.nodes.NODE_T4_5.data.name).to.equal("Shield Wall");
    });

    it("should hydrate all passive skill nodes correctly", () => {
      const fullFactory = new SkillTreeFactory(full30NodeTemplate, fullSkills);
      const tree = fullFactory.createTree(fullClassConfig);

      // PASSIVE_1
      expect(tree.nodes.NODE_T3_4.type).to.equal("PASSIVE_ABILITY");
      expect(tree.nodes.NODE_T3_4.data.effect_id).to.equal("PASSIVE_IRON_SKIN");
      expect(tree.nodes.NODE_T3_4.data.name).to.equal("PASSIVE_IRON_SKIN");

      // PASSIVE_2
      expect(tree.nodes.NODE_T4_6.type).to.equal("PASSIVE_ABILITY");
      expect(tree.nodes.NODE_T4_6.data.effect_id).to.equal("PASSIVE_THORNS");

      // PASSIVE_3
      expect(tree.nodes.NODE_T4_8.type).to.equal("PASSIVE_ABILITY");
      expect(tree.nodes.NODE_T4_8.data.effect_id).to.equal("PASSIVE_REGEN");

      // PASSIVE_4 (if it exists in tier 5)
      if (tree.nodes.NODE_T5_8) {
        expect(tree.nodes.NODE_T5_8.type).to.equal("PASSIVE_ABILITY");
        expect(tree.nodes.NODE_T5_8.data.effect_id).to.equal("PASSIVE_FORTIFY");
      }
    });

    it("should preserve tier, req, and cost properties", () => {
      const fullFactory = new SkillTreeFactory(full30NodeTemplate, fullSkills);
      const tree = fullFactory.createTree(fullClassConfig);

      // Check tier 1 node
      expect(tree.nodes.NODE_T1_1.tier).to.equal(1);
      expect(tree.nodes.NODE_T1_1.req).to.equal(1);
      expect(tree.nodes.NODE_T1_1.cost).to.equal(1);

      // Check tier 5 node
      expect(tree.nodes.NODE_T5_1.tier).to.equal(5);
      expect(tree.nodes.NODE_T5_1.req).to.equal(5);
      expect(tree.nodes.NODE_T5_1.cost).to.equal(3);
    });

    it("should generate tree with correct ID format", () => {
      const fullFactory = new SkillTreeFactory(full30NodeTemplate, fullSkills);
      const tree = fullFactory.createTree(fullClassConfig);

      expect(tree.id).to.equal("TREE_CLASS_VANGUARD");
    });
  });
});
