import { describe, it, expect, beforeEach } from 'vitest';
import { useDisciplineStore } from '../stores/discipline-slice';

function resetDisciplineStore() {
  useDisciplineStore.setState({
    disciplines: {},
    activeIds: [],
    concurrentLimit: 1,
    totalXP: 0,
  });
}

describe('DisciplineStore', () => {
  beforeEach(resetDisciplineStore);

  describe('activate', () => {
    it('should activate raw discipline', () => {
      useDisciplineStore.getState().activate('raw-mastery');
      expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
      expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(false);
    });

    it('should not activate same discipline twice', () => {
      useDisciplineStore.getState().activate('raw-mastery');
      useDisciplineStore.getState().activate('raw-mastery');
      expect(useDisciplineStore.getState().activeIds.filter(id => id === 'raw-mastery').length).toBe(1);
    });

    it('should not activate when concurrent limit reached', () => {
      useDisciplineStore.getState().activate('raw-mastery');
      useDisciplineStore.getState().activate('elemental-attunement');
      expect(useDisciplineStore.getState().activeIds.length).toBe(1);
    });

    it('should activate when no prior discipline state (optimistic)', () => {
      // canProceedDiscipline returns true when disciplineState is undefined
      useDisciplineStore.getState().activate('elemental-attunement', {
        elements: { fire: { unlocked: false } },
      });
      expect(useDisciplineStore.getState().activeIds).toContain('elemental-attunement');
    });

    it('should not activate when existing state has insufficient mana', () => {
      useDisciplineStore.setState({
        disciplines: { 'raw-mastery': { id: 'raw-mastery', xp: 1000, paused: false } },
      });
      useDisciplineStore.getState().activate('raw-mastery', { elements: {} });
      expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery');
    });

    it('should activate when required element is unlocked', () => {
      useDisciplineStore.getState().activate('elemental-attunement', {
        elements: { fire: { unlocked: true } },
      });
      expect(useDisciplineStore.getState().activeIds).toContain('elemental-attunement');
    });
  });

  describe('deactivate', () => {
    it('should remove discipline from active list', () => {
      useDisciplineStore.getState().activate('raw-mastery');
      useDisciplineStore.getState().deactivate('raw-mastery');
      expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery');
    });
  });

  describe('processTick', () => {
    it('should accrue XP for active discipline', () => {
      useDisciplineStore.getState().activate('raw-mastery');
      useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
      expect(useDisciplineStore.getState().disciplines['raw-mastery'].xp).toBe(1);
      expect(useDisciplineStore.getState().totalXP).toBe(1);
    });

    it('should drain raw mana for raw discipline', () => {
      useDisciplineStore.getState().activate('raw-mastery');
      const result = useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
      expect(result.rawMana).toBeLessThan(1000);
    });

    it('should pause discipline when insufficient mana', () => {
      useDisciplineStore.getState().activate('raw-mastery');
      useDisciplineStore.getState().processTick({ rawMana: 0, elements: {} });
      expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(true);
    });

    it('should increase concurrent limit at 500 total XP', () => {
      useDisciplineStore.setState({ totalXP: 499 });
      useDisciplineStore.getState().activate('raw-mastery');
      useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
      expect(useDisciplineStore.getState().totalXP).toBe(500);
      expect(useDisciplineStore.getState().concurrentLimit).toBeGreaterThan(1);
    });
  });
});
