import { describe, it, expect, beforeEach, vi } from 'vitest';
import { computeDisciplineEffects } from '../effects/discipline-effects';
import { useDisciplineStore } from '../stores/discipline-slice';
import { baseDisciplines } from '../data/disciplines/base';

// ─── Test Fixtures ────────────────────────────────────────────────────────────

const rawMastery = baseDisciplines.find((d) => d.id === 'raw-mastery')!;

/**
 * Helper: set the discipline store to a known state.
 * We use the store's setState directly so we can control exactly what
 * computeDisciplineEffects sees when it calls getState().
 */
function setDisciplineState(overrides: Partial<ReturnType<typeof useDisciplineStore.getState>>) {
  useDisciplineStore.setState(overrides as any);
}

// ─── Bug B: autoPaused disciplines should still contribute stat bonuses ───────

describe('computeDisciplineEffects — autoPaused discipline bonuses (Bug B)', () => {
  beforeEach(() => {
    // Reset to clean state
    setDisciplineState({
      disciplines: {},
      activeIds: [],
    });
  });

  it('should include stat bonuses from an auto-paused discipline with XP', () => {
    setDisciplineState({
      disciplines: {
        'raw-mastery': { id: 'raw-mastery', xp: 1000, paused: false, autoPaused: true },
      },
      activeIds: ['raw-mastery'],
    });

    const effects = computeDisciplineEffects();
    expect(effects.bonuses.maxManaBonus).toBeGreaterThan(0);
  });

  it('should NOT include stat bonuses from a manually paused discipline', () => {
    setDisciplineState({
      disciplines: {
        'raw-mastery': { id: 'raw-mastery', xp: 1000, paused: true, autoPaused: false },
      },
      activeIds: [],
    });

    const effects = computeDisciplineEffects();
    expect(effects.bonuses.maxManaBonus || 0).toBe(0);
  });

  it('should include stat bonuses from an active (non-paused) discipline', () => {
    setDisciplineState({
      disciplines: {
        'raw-mastery': { id: 'raw-mastery', xp: 500, paused: false, autoPaused: false },
      },
      activeIds: ['raw-mastery'],
    });

    const effects = computeDisciplineEffects();
    expect(effects.bonuses.maxManaBonus).toBeGreaterThan(0);
  });

  it('auto-paused discipline with 0 XP should not contribute bonuses', () => {
    setDisciplineState({
      disciplines: {
        'raw-mastery': { id: 'raw-mastery', xp: 0, paused: false, autoPaused: true },
      },
      activeIds: ['raw-mastery'],
    });

    const effects = computeDisciplineEffects();
    expect(effects.bonuses.maxManaBonus || 0).toBe(0);
  });

  it('should distinguish autoPaused from paused: mixed scenario', () => {
    setDisciplineState({
      disciplines: {
        'raw-mastery': { id: 'raw-mastery', xp: 1000, paused: false, autoPaused: true },
      },
      activeIds: ['raw-mastery'],
    });

    const effects = computeDisciplineEffects();
    // autoPaused=true, paused=false → should be included
    expect(effects.bonuses.maxManaBonus).toBeGreaterThan(0);

    // Now manually pause it
    setDisciplineState({
      disciplines: {
        'raw-mastery': { id: 'raw-mastery', xp: 1000, paused: true, autoPaused: false },
      },
      activeIds: [],
    });

    const effects2 = computeDisciplineEffects();
    expect(effects2.bonuses.maxManaBonus || 0).toBe(0);
  });
});

// ─── Bug A concept: computeDisciplineEffects reads current state ──────────────

describe('computeDisciplineEffects — reactive state reads (Bug A)', () => {
  beforeEach(() => {
    setDisciplineState({
      disciplines: {},
      activeIds: [],
    });
  });

  it('should return updated bonuses when discipline XP changes in the store', () => {
    // Start with some XP
    setDisciplineState({
      disciplines: {
        'raw-mastery': { id: 'raw-mastery', xp: 100, paused: false, autoPaused: false },
      },
      activeIds: ['raw-mastery'],
    });

    const effects1 = computeDisciplineEffects();
    const bonus1 = effects1.bonuses.maxManaBonus;
    expect(bonus1).toBeGreaterThan(0);

    // Simulate tick: XP increases
    setDisciplineState({
      disciplines: {
        'raw-mastery': { id: 'raw-mastery', xp: 5000, paused: false, autoPaused: false },
      },
      activeIds: ['raw-mastery'],
    });

    const effects2 = computeDisciplineEffects();
    const bonus2 = effects2.bonuses.maxManaBonus;

    // Higher XP → higher bonus (stat bonus is monotonically increasing)
    expect(bonus2).toBeGreaterThan(bonus1);
  });

  it('should return zero bonuses when store is empty (fresh game)', () => {
    setDisciplineState({
      disciplines: {},
      activeIds: [],
    });

    const effects = computeDisciplineEffects();
    expect(effects.bonuses.maxManaBonus || 0).toBe(0);
  });
});
