import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { useGameStore } from '../stores/gameStore';
import { useManaStore, makeInitialElements } from '../stores/manaStore';
import { useCombatStore } from '../stores/combatStore';
import { usePrestigeStore } from '../stores/prestigeStore';
import { useUIStore } from '../stores/uiStore';
import { useDisciplineStore } from '../stores/discipline-slice';
import { useAttunementStore } from '../stores/attunementStore';
import { useCraftingStore } from '../stores/craftingStore';
import { getFloorMaxHP } from '../utils';
import { ELEMENTS } from '../constants';

// ─── Helpers ──────────────────────────────────────────────────────────────────

function resetAllStores() {
  useUIStore.setState({
    paused: false,
    gameOver: false,
    victory: false,
    logs: [],
  });

  useGameStore.setState({
    day: 1,
    hour: 0,
    incursionStrength: 0,
    containmentWards: 0,
    initialized: true,
  });

  useManaStore.setState({
    rawMana: 100,
    meditateTicks: 0,
    totalManaGathered: 0,
    elements: makeInitialElements(50, {}),
  });

  useCombatStore.setState({
    currentFloor: 1,
    floorHP: getFloorMaxHP(1),
    floorMaxHP: getFloorMaxHP(1),
    maxFloorReached: 1,
    activeSpell: 'manaBolt',
    currentAction: 'meditate',
    castProgress: 0,
    spireMode: false,
    currentRoom: { roomType: 'combat', enemies: [] },
    clearedFloors: {},
    climbDirection: null,
    isDescending: false,
    golemancy: { activeGolems: [], lastSummonFloor: 0, golemDesigns: {}, golemLoadout: [] },
    equipmentSpellStates: [],
    comboHitCount: 0,
    floorHitCount: 0,
    spells: { manaBolt: { learned: true, level: 1, studyProgress: 0 } },
    activityLog: [],
    achievements: { unlocked: [], progress: {} },
    totalSpellsCast: 0,
    totalDamageDealt: 0,
    totalCraftsCompleted: 0,
  });

  usePrestigeStore.setState({
    loopCount: 0,
    insight: 0,
    totalInsight: 0,
    loopInsight: 0,
    prestigeUpgrades: {},
    pactSlots: 1,
    defeatedGuardians: [],
    signedPacts: [],
    signedPactDetails: {},
    pactRitualFloor: null,
    pactRitualProgress: 0,
  });

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

  useAttunementStore.setState({
    attunements: {},
  });

  useCraftingStore.setState({
    designProgress: null,
    designProgress2: null,
    preparationProgress: null,
    applicationProgress: null,
    equipmentCraftingProgress: null,
    completedEnchantmentDesigns: [],
    unlockedEffects: [],
    equippedInstances: {},
    equipmentInstances: {},
    lootInventory: {
      materials: {},
      blueprints: [],
    },
    enchantmentSelection: {
      selectedEquipmentType: null,
      selectedEffects: [],
      designName: '',
      selectedDesign: null,
      selectedEquipmentInstance: null,
    },
    lastError: null,
  });
}

function unlockAllElements() {
  const mana = useManaStore.getState();
  for (const elem of Object.keys(ELEMENTS)) {
    if (!mana.elements[elem]?.unlocked) {
      // Directly set unlocked (simulating debug "Unlock All")
      useManaStore.setState({
        elements: {
          ...useManaStore.getState().elements,
          [elem]: { ...useManaStore.getState().elements[elem], unlocked: true, current: 0 },
        },
      });
    }
  }
}

function countPausedLogs(logs: string[]): number {
  return logs.filter(l => l.includes('⚠️ PAUSED')).length;
}

// ─── Tests ────────────────────────────────────────────────────────────────────

describe('Paused conversion log deduplication (bug #337)', () => {
  beforeEach(() => {
    resetAllStores();
  });

  it('should log each paused conversion only once across many ticks', () => {
    unlockAllElements();

    // Run 50 ticks (10 seconds of game time at 200ms/tick)
    for (let i = 0; i < 50; i++) {
      useGameStore.getState().tick();
    }

    const logs = useUIStore.getState().logs;
    const pausedCount = countPausedLogs(logs);

    // With 22 elements unlocked but only transference having regen,
    // many conversions will be paused. Before the fix, this would
    // produce 50+ duplicate messages per tick (1000+ total).
    // After the fix, each unique paused conversion should appear at most once.
    // The exact count depends on how many elements have conversion rates,
    // but it should be a small constant, not proportional to tick count.
    expect(pausedCount).toBeLessThan(30);
  });

  it('should not produce more PAUSED logs after the first tick for the same state', () => {
    unlockAllElements();

    // First tick: should log paused conversions
    useGameStore.getState().tick();
    const logsAfterFirst = useUIStore.getState().logs;
    const pausedAfterFirst = countPausedLogs(logsAfterFirst);

    // Run 99 more ticks with unchanged state
    for (let i = 0; i < 99; i++) {
      useGameStore.getState().tick();
    }
    const logsAfter100 = useUIStore.getState().logs;
    const pausedAfter100 = countPausedLogs(logsAfter100);

    // The count should be identical — no new PAUSED messages after tick 1
    expect(pausedAfter100).toBe(pausedAfterFirst);
  });

  it('should re-log a conversion if it un-pauses and re-pauses', () => {
    unlockAllElements();

    // First tick: logs paused conversions
    useGameStore.getState().tick();
    const pausedAfterFirst = countPausedLogs(useUIStore.getState().logs);

    // Give enough raw regen to un-pause some conversions
    useManaStore.setState({
      rawMana: 999999,
    });

    // Run a tick — conversions should un-pause (loggedPausedConversions cleans up)
    useGameStore.getState().tick();

    // Now set raw regen low again by draining raw mana to 0
    // (conversions will pause again due to insufficient regen)
    useManaStore.setState({
      rawMana: 0,
    });

    // Run another tick — conversions should re-pause and re-log
    useGameStore.getState().tick();
    const pausedAfterRepause = countPausedLogs(useUIStore.getState().logs);

    // Should have at least as many as before (re-paused conversions re-log)
    expect(pausedAfterRepause).toBeGreaterThanOrEqual(pausedAfterFirst);
  });

  it('should produce zero PAUSED logs when all conversions are active', () => {
    // Only transference unlocked (default), with enough raw regen
    useManaStore.setState({
      rawMana: 999999,
    });

    for (let i = 0; i < 20; i++) {
      useGameStore.getState().tick();
    }

    const pausedCount = countPausedLogs(useUIStore.getState().logs);
    expect(pausedCount).toBe(0);
  });
});
