import { beforeEach, describe, expect, it, vi } from 'vitest';

const queryMock = vi.fn();
const executeMock = vi.fn();

vi.mock('../../src/database/pool.js', () => ({
  query: queryMock,
  execute: executeMock,
}));

describe('event instance persistence', () => {
  beforeEach(() => {
    queryMock.mockReset();
    executeMock.mockReset();
  });

  it('creates an event instance row', async () => {
    executeMock.mockResolvedValue({ affectedRows: 1 });

    const { createEventInstance } = await import('../../src/database/eventInstances.js');

    const created = await createEventInstance({
      instanceId: 'evt-inst-1',
      playerId: 'player-1',
      eventId: 'dilemma_found_wallet',
      prompt: 'You found a wallet. What do you do?',
      choices: [
        { choiceId: 'return_wallet', text: 'Return it to the owner' },
        { choiceId: 'keep_cash', text: 'Keep the cash' },
      ],
      context: { category: 'dilemma' },
    });

    expect(executeMock).toHaveBeenCalledTimes(1);
    expect(created.instanceId).toBe('evt-inst-1');
    expect(created.status).toBe('pending');
  });

  it('loads pending instances for a player', async () => {
    queryMock.mockResolvedValue([
      {
        instance_id: 'evt-inst-1',
        player_id: 'player-1',
        event_id: 'dilemma_found_wallet',
        status: 'pending',
        prompt: 'You found a wallet. What do you do?',
        choices_json: JSON.stringify([{ choiceId: 'return_wallet', text: 'Return it to the owner' }]),
        context_json: JSON.stringify({ category: 'dilemma' }),
        selected_choice_id: null,
        created_at: new Date('2026-02-11T00:00:00.000Z'),
        answered_at: null,
        resolved_at: null,
      },
    ]);

    const { getPendingEventInstances } = await import('../../src/database/eventInstances.js');

    const rows = await getPendingEventInstances('player-1');

    expect(queryMock).toHaveBeenCalledTimes(1);
    expect(rows).toHaveLength(1);
    expect(rows[0].instanceId).toBe('evt-inst-1');
    expect(rows[0].choices[0].choiceId).toBe('return_wallet');
  });

  it('marks an instance as answered', async () => {
    executeMock.mockResolvedValue({ affectedRows: 1 });

    const { answerEventInstance } = await import('../../src/database/eventInstances.js');

    const ok = await answerEventInstance('evt-inst-1', 'return_wallet');

    expect(ok).toBe(true);
    expect(executeMock).toHaveBeenCalledTimes(1);
  });

  it('marks an instance as resolved', async () => {
    executeMock.mockResolvedValue({ affectedRows: 1 });

    const { resolveEventInstance } = await import('../../src/database/eventInstances.js');

    const ok = await resolveEventInstance('evt-inst-1', {
      resolutionText: 'You returned it.',
      effects: { stats: { happiness: 10 } },
    });

    expect(ok).toBe(true);
    expect(executeMock).toHaveBeenCalledTimes(1);
  });
});
