// ─── Test: computeGolemStats ──────────────────────────────────────────────────

describe('computeGolemStats', () => {
  it('computes stats for a basic golem design', async () => {
    const { CORES, FRAMES, MIND_CIRCUITS } = await import('@/lib/game/data/golems');
    const { computeGolemStats } = await import('@/lib/game/data/golems/utils');

    const design = {
      id: 'test_basic',
      name: 'Test Basic',
      core: CORES.basic,
      frame: FRAMES.earth,
      mindCircuit: MIND_CIRCUITS.simple,
      enchantments: [],
      selectedManaTypes: [],
      selectedSpells: [],
    };

    const stats = computeGolemStats(design);

    // Core-derived stats
    expect(stats.manaCapacity).toBe(50);
    expect(stats.manaRegen).toBe(0.5);
    expect(stats.maxRoomDuration).toBe(3);

    // Frame-derived stats
    expect(stats.baseDamage).toBe(6);
    expect(stats.attackSpeed).toBe(1.2);
    expect(stats.armorPierce).toBe(0.05);
    expect(stats.magicAffinity).toBe(0.3);
    expect(stats.aoeTargets).toBe(1);

    // Circuit-derived stats
    expect(stats.spellSlots).toBe(0);

    // Enchantment capacity = Math.round(frame.magicAffinity * 100) * core.tierMultiplier
    expect(stats.enchantmentCapacity).toBeCloseTo(Math.round(0.3 * 100) * 1.0);

    // Special effect from frame
    expect(stats.specialEffect).toBe('none');

    // Available mana types from core
    expect(stats.availableManaTypes).toEqual(['earth']);
  });

  it('computes stats for an advanced golem with enchantments', async () => {
    const { CORES, FRAMES, MIND_CIRCUITS, GOLEM_ENCHANTMENTS } = await import('@/lib/game/data/golems');
    const { computeGolemStats } = await import('@/lib/game/data/golems/utils');

    const design = {
      id: 'test_advanced',
      name: 'Test Advanced',
      core: CORES.advanced,
      frame: FRAMES.steel,
      mindCircuit: MIND_CIRCUITS.advanced,
      enchantments: [GOLEM_ENCHANTMENTS.sword_fire, GOLEM_ENCHANTMENTS.sword_metal],
      selectedManaTypes: ['crystal', 'metal', 'fire'],
      selectedSpells: [],
    };

    const stats = computeGolemStats(design);

    // Core-derived stats
    expect(stats.manaCapacity).toBe(200);
    expect(stats.manaRegen).toBe(3.0);
    expect(stats.maxRoomDuration).toBe(5);

    // Frame-derived stats
    expect(stats.baseDamage).toBe(18);
    expect(stats.attackSpeed).toBe(1.6);
    expect(stats.armorPierce).toBe(0.5);
    expect(stats.magicAffinity).toBe(0.5);

    // Circuit-derived stats
    expect(stats.spellSlots).toBe(2);

    // Enchantment capacity = Math.round(frame.magicAffinity * 100) * core.tierMultiplier
    expect(stats.enchantmentCapacity).toBeCloseTo(Math.round(0.5 * 100) * 2.0);

    // Selected mana types override core defaults
    expect(stats.availableManaTypes).toEqual(['crystal', 'metal', 'fire']);

    // Total summon cost includes all components + enchantments
    expect(stats.totalSummonCost.length).toBeGreaterThan(0);

    // Upkeep = core.manaRegen * 2 per hour, split across selected mana types
    expect(stats.upkeepCostPerHour.length).toBe(3); // crystal, metal, fire
    expect(stats.upkeepCostPerHour[0].amount).toBe(2.0); // 6.0 / 3
    expect(stats.upkeepCostPerHour[0].element).toBe('crystal');
    expect(stats.upkeepCostPerHour[1].amount).toBe(2.0);
    expect(stats.upkeepCostPerHour[1].element).toBe('metal');
    expect(stats.upkeepCostPerHour[2].amount).toBe(2.0);
    expect(stats.upkeepCostPerHour[2].element).toBe('fire');
  });

  it('computes total summon cost from all components', async () => {
    const { CORES, FRAMES, MIND_CIRCUITS } = await import('@/lib/game/data/golems');
    const { computeGolemStats } = await import('@/lib/game/data/golems/utils');

    const design = {
      id: 'test_cost',
      name: 'Test Cost',
      core: CORES.basic,
      frame: FRAMES.earth,
      mindCircuit: MIND_CIRCUITS.simple,
      enchantments: [],
      selectedManaTypes: [],
      selectedSpells: [],
    };

    const stats = computeGolemStats(design);

    // basic core: 10 earth, earth frame: 5 raw, simple circuit: 3 earth (spec §6.1)
    const rawCosts = stats.totalSummonCost.filter(c => c.type === 'raw');
    const earthCosts = stats.totalSummonCost.filter(c => c.type === 'element' && c.element === 'earth');

    const totalRaw = rawCosts.reduce((sum, c) => sum + c.amount, 0);
    const totalEarth = earthCosts.reduce((sum, c) => sum + c.amount, 0);

    expect(totalRaw).toBe(5); // earth frame only
    expect(totalEarth).toBe(13); // basic core 10 + simple circuit 3
  });
});

// ─── Test: canAffordGolemDesign ───────────────────────────────────────────────

describe('canAffordGolemDesign', () => {
  it('returns canAfford true when player has enough resources', async () => {
    const { CORES, FRAMES, MIND_CIRCUITS } = await import('@/lib/game/data/golems');
    const { canAffordGolemDesign } = await import('@/lib/game/data/golems/utils');

    const design = {
      id: 'test_afford',
      name: 'Test Afford',
      core: CORES.basic,
      frame: FRAMES.earth,
      mindCircuit: MIND_CIRCUITS.simple,
      enchantments: [],
      selectedManaTypes: [],
      selectedSpells: [],
    };

    // basic core: 10 earth, earth frame: 5 raw, simple circuit: 3 earth (spec §6.1)
    const result = canAffordGolemDesign(design, 100, {
      earth: { current: 50, max: 100, unlocked: true },
    });

    expect(result.canAfford).toBe(true);
    expect(result.missing).toBe('');
  });

  it('returns canAfford false when raw mana is insufficient', async () => {
    const { CORES, FRAMES, MIND_CIRCUITS } = await import('@/lib/game/data/golems');
    const { canAffordGolemDesign } = await import('@/lib/game/data/golems/utils');

    const design = {
      id: 'test_no_raw',
      name: 'Test No Raw',
      core: CORES.basic,
      frame: FRAMES.earth,
      mindCircuit: MIND_CIRCUITS.simple,
      enchantments: [],
      selectedManaTypes: [],
      selectedSpells: [],
    };

    // Need 5 raw total (earth frame only, circuit uses earth mana now), only have 3
    const result = canAffordGolemDesign(design, 3, {
      earth: { current: 50, max: 100, unlocked: true },
    });

    expect(result.canAfford).toBe(false);
    expect(result.missing).toContain('raw mana');
  });

  it('returns canAfford false when element mana is insufficient', async () => {
    const { CORES, FRAMES, MIND_CIRCUITS } = await import('@/lib/game/data/golems');
    const { canAffordGolemDesign } = await import('@/lib/game/data/golems/utils');

    const design = {
      id: 'test_no_elem',
      name: 'Test No Elem',
      core: CORES.basic,
      frame: FRAMES.earth,
      mindCircuit: MIND_CIRCUITS.simple,
      enchantments: [],
      selectedManaTypes: [],
      selectedSpells: [],
    };

    // Need 10 earth, only have 5
    const result = canAffordGolemDesign(design, 100, {
      earth: { current: 5, max: 100, unlocked: true },
    });

    expect(result.canAfford).toBe(false);
    expect(result.missing).toContain('earth');
  });

  it('returns canAfford false when element is not unlocked', async () => {
    const { CORES, FRAMES, MIND_CIRCUITS } = await import('@/lib/game/data/golems');
    const { canAffordGolemDesign } = await import('@/lib/game/data/golems/utils');

    const design = {
      id: 'test_locked',
      name: 'Test Locked',
      core: CORES.basic,
      frame: FRAMES.earth,
      mindCircuit: MIND_CIRCUITS.simple,
      enchantments: [],
      selectedManaTypes: [],
      selectedSpells: [],
    };

    // earth not in elements at all
    const result = canAffordGolemDesign(design, 100, {});

    expect(result.canAfford).toBe(false);
    expect(result.missing).toContain('not unlocked');
  });

  it('returns canAfford false when element exists but unlocked is false', async () => {
    const { CORES, FRAMES, MIND_CIRCUITS } = await import('@/lib/game/data/golems');
    const { canAffordGolemDesign } = await import('@/lib/game/data/golems/utils');

    const design = {
      id: 'test_unlocked_false',
      name: 'Test Unlocked False',
      core: CORES.basic,
      frame: FRAMES.earth,
      mindCircuit: MIND_CIRCUITS.simple,
      enchantments: [],
      selectedManaTypes: [],
      selectedSpells: [],
    };

    const result = canAffordGolemDesign(design, 100, {
      earth: { current: 50, max: 100, unlocked: false },
    });

    expect(result.canAfford).toBe(false);
    expect(result.missing).toContain('not unlocked');
  });
});

// ─── Test: Combat store golemancy state ───────────────────────────────────────

describe('Combat store golemancy', () => {
  it('toggleGolemLoadoutEntry is a function', async () => {
    const { useCombatStore } = await import('@/lib/game/stores/combatStore');
    const state = useCombatStore.getState();
    expect(typeof state.toggleGolemLoadoutEntry).toBe('function');
  });

  it('addGolemDesign is a function', async () => {
    const { useCombatStore } = await import('@/lib/game/stores/combatStore');
    const state = useCombatStore.getState();
    expect(typeof state.addGolemDesign).toBe('function');
  });

  it('golemancy state has correct shape', async () => {
    const { useCombatStore } = await import('@/lib/game/stores/combatStore');
    const state = useCombatStore.getState();
    expect(state.golemancy).toBeDefined();
    expect(Array.isArray(state.golemancy.golemLoadout)).toBe(true);
    expect(Array.isArray(state.golemancy.activeGolems)).toBe(true);
  });
});

// ─── Test: File size limit ────────────────────────────────────────────────────

describe('File size limits (400 lines max)', () => {
  it('GolemancyTab.tsx is under 400 lines', async () => {
    const fs = await import('fs');
    const path = await import('path');
    const filePath = path.join(__dirname, '..', 'GolemancyTab.tsx');
    const content = fs.readFileSync(filePath, 'utf-8');
    const lines = content.split('\n').length;
    expect(lines).toBeLessThan(400);
  });
});
