import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { act, fireEvent, render, screen } from '@testing-library/react';
import { MEMORY_MAX_ATTEMPTS, MemoryGame } from '../../src/components/minigames/MemoryGame';

describe('MemoryGame', () => {
  beforeEach(() => {
    vi.useFakeTimers();
    vi.spyOn(Math, 'random').mockReturnValue(0);
  });

  afterEach(() => {
    vi.useRealTimers();
    vi.restoreAllMocks();
  });

  it('renders all 12 cards and the attempt counter', () => {
    render(<MemoryGame onSuccess={vi.fn()} onFail={vi.fn()} />);

    expect(screen.getByText(/Memory Game/i)).toBeTruthy();
    expect(screen.getByText(new RegExp(`Attempts: 0/${MEMORY_MAX_ATTEMPTS}`))).toBeTruthy();
    expect(screen.getAllByRole('button').length).toBe(12);
  });

  it('increments attempts per resolved turn', () => {
    render(<MemoryGame onSuccess={vi.fn()} onFail={vi.fn()} />);

    const cards = screen.getAllByRole('button');
    fireEvent.click(cards[0]);
    fireEvent.click(cards[1]);
    act(() => {
      vi.advanceTimersByTime(850);
    });

    expect(screen.getByText(/Attempts: 1\/18/i)).toBeTruthy();
  });

  it('fails when the turn budget is exhausted', () => {
    const onFail = vi.fn();
    render(<MemoryGame onSuccess={vi.fn()} onFail={onFail} />);

    for (let attempt = 0; attempt < MEMORY_MAX_ATTEMPTS; attempt += 1) {
      const cards = screen.getAllByRole('button');
      fireEvent.click(cards[0]);
      fireEvent.click(cards[1]);
      act(() => {
        vi.advanceTimersByTime(850);
      });
    }

    act(() => {
      vi.runOnlyPendingTimers();
    });
    expect(onFail).toHaveBeenCalledTimes(1);
  });
});
