// ─── Regression Test: Hasty Enchanter 25% Design Speed Bonus ──────────────────
// Bug #301: Hasty Enchanter applied ~6.25% speed increase (additive 0.01 per tick)
// instead of the spec-defined 25% (time *= 0.75, i.e. 4/3 progress per tick).

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

function makeComputedEffects(specials: string[] = []) {
  return {
    maxManaMultiplier: 1,
    maxManaBonus: 0,
    regenMultiplier: 1,
    regenBonus: 0,
    clickManaMultiplier: 1,
    clickManaBonus: 0,
    meditationEfficiency: 1,
    spellCostMultiplier: 1,
    conversionEfficiency: 0,
    baseDamageMultiplier: 1,
    baseDamageBonus: 0,
    attackSpeedMultiplier: 1,
    critChanceBonus: 0,
    critDamageMultiplier: 1,
    elementalDamageMultiplier: 1,
    studySpeedMultiplier: 1,
    studyCostMultiplier: 1,
    progressRetention: 0,
    instantStudyChance: 0,
    freeStudyChance: 0,
    elementCapMultiplier: 1,
    elementCapBonus: 0,
    perElementCapBonus: {},
    perElementRegenBonus: {},
    conversionCostMultiplier: 1,
    doubleCraftChance: 0,
    permanentRegenBonus: 0,
    specials: new Set(specials),
    activeUpgrades: [],
    skillLevelMultiplier: 1,
    enchantmentPowerMultiplier: 1,
  };
}

describe('Hasty Enchanter — design speed bonus', () => {
  it('should apply 4/3 progress per tick (not additive 0.01) for repeat designs', () => {
    const effects = makeComputedEffects(['hastyEnchanter']);
    const required = 2; // 2 hours required
    const result = calculateDesignProgress(0, required, effects, true);

    // Expected: progress = HOURS_PER_TICK * (4/3) = 0.04 * 1.333... = 0.05333...
    const expectedProgress = HOURS_PER_TICK * (4 / 3);
    expect(result.progress).toBeCloseTo(expectedProgress, 10);
    expect(result.isComplete).toBe(false);
  });

  it('should reduce total ticks to 75% of original (25% faster)', () => {
    const effects = makeComputedEffects(['hastyEnchanter']);
    const required = 2; // 2 hours required

    // Without haste: ticks needed = 2 / 0.04 = 50 ticks
    // With haste (4/3 multiplier): effective progress per tick = 0.04 * 4/3 = 0.05333...
    // Ticks needed with haste = 2 / 0.05333... = 37.5 ticks
    // Ratio = 37.5 / 50 = 0.75

    let progress = 0;
    let ticks = 0;
    while (progress < required) {
      const result = calculateDesignProgress(progress, required, effects, true);
      progress = result.progress;
      ticks++;
      if (ticks > 1000) break; // safety valve
    }

    // 50 ticks * 0.75 = 37.5 ticks expected
    expect(ticks).toBeLessThanOrEqual(38);
    expect(ticks).toBeGreaterThanOrEqual(37);
  });

  it('should NOT apply haste bonus for first-time designs (isRepeatDesign=false)', () => {
    const effects = makeComputedEffects(['hastyEnchanter']);
    const required = 2;
    const result = calculateDesignProgress(0, required, effects, false);

    // Without haste: progress = HOURS_PER_TICK = 0.04
    expect(result.progress).toBeCloseTo(HOURS_PER_TICK, 10);
    expect(result.timeBonus).toBe(0);
  });

  it('should NOT apply haste bonus without HASTY_ENCHANTER special', () => {
    const effects = makeComputedEffects([]); // no specials
    const required = 2;
    const result = calculateDesignProgress(0, required, effects, true);

    expect(result.progress).toBeCloseTo(HOURS_PER_TICK, 10);
    expect(result.timeBonus).toBe(0);
  });

  it('timeBonus should reflect the extra progress beyond base tick', () => {
    const effects = makeComputedEffects(['hastyEnchanter']);
    const required = 2;
    const result = calculateDesignProgress(0, required, effects, true);

    // timeBonus = hastedIncrement - baseIncrement = (0.04 * 4/3) - 0.04 = 0.04 * (1/3) ≈ 0.01333...
    const expectedBonus = HOURS_PER_TICK * (1 / 3);
    expect(result.timeBonus).toBeCloseTo(expectedBonus, 10);
  });
});
