// ─── Regression Test: Issue #353 ──────────────────────────────────────────────
// Preparation mana never deducted — free equipment preparation exploit
//
// Bug: startPreparing() validated rawMana >= costs.manaTotal but never called
// useManaStore.setState() to deduct the cost. cancelPreparation() refunds
// manaCostPaid, so canceling after preparing created mana from nothing.
//
// Fix: Added useManaStore.setState() call to deduct costs in startPreparing().

import { describe, it, expect, beforeEach } from 'vitest';
import { useManaStore } from '../stores/manaStore';
import { useCraftingStore } from '../stores/craftingStore';
import { startPreparing, cancelPreparation } from '../crafting-actions/preparation-actions';

describe('Issue #353 — Preparation mana deduction', () => {
  beforeEach(() => {
    localStorage.removeItem('mana-loop-mana');
    localStorage.removeItem('mana-loop-crafting');
    useManaStore.getState().resetMana({});
    useCraftingStore.getState().resetCrafting?.();
  });

  it('should deduct raw mana when starting preparation', () => {
    // Set up: give the player plenty of raw mana
    useManaStore.setState({ rawMana: 10000 });

    // Create a basic equipment instance in the crafting store
    const testInstanceId = 'test-staff-1';
    const testEquipment = {
      instanceId: testInstanceId,
      typeId: 'basicStaff',
      name: 'Test Staff',
      enchantments: [],
      usedCapacity: 0,
      totalCapacity: 50,
      rarity: 'common' as const,
      quality: 1,
      tags: [],
    };

    useCraftingStore.setState((s) => ({
      equipmentInstances: { ...s.equipmentInstances, [testInstanceId]: testEquipment },
    }));

    const rawManaBefore = useManaStore.getState().rawMana;
    const get = () => useCraftingStore.getState();
    const set = (partial: any) => useCraftingStore.setState(partial);

    const result = startPreparing(testInstanceId, rawManaBefore, get, set);

    expect(result).toBe(true);
    // Mana should have been deducted
    const rawManaAfter = useManaStore.getState().rawMana;
    expect(rawManaAfter).toBeLessThan(rawManaBefore);
  });

  it('should not deduct mana when starting preparation fails (insufficient mana)', () => {
    // Set up: give the player zero raw mana
    useManaStore.setState({ rawMana: 0 });

    const testInstanceId = 'test-staff-2';
    const testEquipment = {
      instanceId: testInstanceId,
      typeId: 'basicStaff',
      name: 'Test Staff',
      enchantments: [],
      usedCapacity: 0,
      totalCapacity: 50,
      rarity: 'common' as const,
      quality: 1,
      tags: [],
    };

    useCraftingStore.setState((s) => ({
      equipmentInstances: { ...s.equipmentInstances, [testInstanceId]: testEquipment },
    }));

    const rawManaBefore = useManaStore.getState().rawMana;
    const get = () => useCraftingStore.getState();
    const set = (partial: any) => useCraftingStore.setState(partial);

    const result = startPreparing(testInstanceId, rawManaBefore, get, set);

    expect(result).toBe(false);
    // Mana should NOT have changed
    expect(useManaStore.getState().rawMana).toBe(rawManaBefore);
  });

  it('cancelPreparation should not create mana (no exploit)', () => {
    // Set up: give the player exactly 5000 raw mana
    const initialMana = 5000;
    useManaStore.setState({ rawMana: initialMana });

    const testInstanceId = 'test-staff-3';
    const testEquipment = {
      instanceId: testInstanceId,
      typeId: 'basicStaff',
      name: 'Test Staff',
      enchantments: [],
      usedCapacity: 0,
      totalCapacity: 50,
      rarity: 'common' as const,
      quality: 1,
      tags: [],
    };

    useCraftingStore.setState((s) => ({
      equipmentInstances: { ...s.equipmentInstances, [testInstanceId]: testEquipment },
    }));

    const get = () => useCraftingStore.getState();
    const set = (partial: any) => useCraftingStore.setState(partial);

    // Start preparation (deducts mana)
    const result = startPreparing(testInstanceId, initialMana, get, set);
    expect(result).toBe(true);

    const manaAfterPrepare = useManaStore.getState().rawMana;
    expect(manaAfterPrepare).toBeLessThan(initialMana);

    // Cancel preparation (refunds proportionally)
    cancelPreparation(get, set);

    const manaAfterCancel = useManaStore.getState().rawMana;
    // After cancel, mana should be LESS than or equal to initial (not more!)
    // The refund is partial (50% for spent progress), so player loses some mana
    expect(manaAfterCancel).toBeLessThanOrEqual(initialMana);
  });
});
