// ─── Regression Test: Discipline Perk Gating in Design Validation ─────────────
// Bug #302: validateDesignEffects() did not check unlockedEffects,
// allowing any effect to be used regardless of discipline perks.

import { describe, it, expect } from 'vitest';
import { validateDesignEffects } from '../crafting-design';

describe('validateDesignEffects — discipline perk gating', () => {
  it('should reject effects not in unlockedEffects', () => {
    const result = validateDesignEffects(
      [{ effectId: 'spell_manaBolt', stacks: 1 }],
      'basicStaff',
      1,
      [] // nothing unlocked
    );
    expect(result.valid).toBe(false);
    expect(result.reason).toContain('locked');
  });

  it('should accept effects that are in unlockedEffects', () => {
    const result = validateDesignEffects(
      [{ effectId: 'spell_manaBolt', stacks: 1 }],
      'basicStaff',
      1,
      ['spell_manaBolt']
    );
    expect(result.valid).toBe(true);
  });

  it('should reject when only some effects are unlocked', () => {
    const result = validateDesignEffects(
      [
        { effectId: 'spell_manaBolt', stacks: 1 },
        { effectId: 'spell_fireball', stacks: 1 },
      ],
      'basicStaff',
      1,
      ['spell_manaBolt'] // fireball not unlocked
    );
    expect(result.valid).toBe(false);
    expect(result.reason).toContain('spell_fireball');
  });

  it('should accept when all effects are unlocked', () => {
    const result = validateDesignEffects(
      [
        { effectId: 'spell_manaBolt', stacks: 1 },
        { effectId: 'spell_fireball', stacks: 1 },
      ],
      'basicStaff',
      1,
      ['spell_manaBolt', 'spell_fireball']
    );
    expect(result.valid).toBe(true);
  });

  it('should accept when unlockedEffects is empty array and effects list is empty', () => {
    const result = validateDesignEffects(
      [],
      'basicStaff',
      1,
      []
    );
    // Empty effects list: no effects to gate, but base validation (enchanting level, equip type) still applies
    expect(result.valid).toBe(true);
  });

  it('should default to empty unlockedEffects when not provided (backward compat)', () => {
    // Without the 4th argument, all effects should be rejected
    const result = validateDesignEffects(
      [{ effectId: 'spell_manaBolt', stacks: 1 }],
      'basicStaff',
      1
    );
    expect(result.valid).toBe(false);
    expect(result.reason).toContain('locked');
  });

  it('should still reject unknown effects even when unlocked', () => {
    const result = validateDesignEffects(
      [{ effectId: 'nonexistent_effect', stacks: 1 }],
      'basicStaff',
      1,
      ['nonexistent_effect']
    );
    expect(result.valid).toBe(false);
    expect(result.reason).toContain('Unknown');
  });

  it('should still reject effects on wrong equipment category even when unlocked', () => {
    // spell_manaBolt is only allowed on 'caster', not 'body'
    const result = validateDesignEffects(
      [{ effectId: 'spell_manaBolt', stacks: 1 }],
      'civilianShirt', // body slot, category 'body'
      1,
      ['spell_manaBolt']
    );
    expect(result.valid).toBe(false);
    expect(result.reason).toContain('not allowed');
  });
});
