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

vi.mock('../../src/components/minigames/TriviaGame', () => ({
  TriviaGame: ({ onSuccess, onFail }: { onSuccess: () => void; onFail: () => void }) => (
    <div>
      <h3>Mock Trivia</h3>
      <button onClick={onSuccess}>Win Mini-game</button>
      <button onClick={onFail}>Lose Mini-game</button>
    </div>
  ),
}));

vi.mock('../../src/components/minigames/MemoryGame', () => ({
  MemoryGame: ({ onSuccess, onFail }: { onSuccess: () => void; onFail: () => void }) => (
    <div>
      <h3>Mock Memory</h3>
      <button onClick={onSuccess}>Win Mini-game</button>
      <button onClick={onFail}>Lose Mini-game</button>
    </div>
  ),
}));

vi.mock('../../src/components/minigames/ReactionGame', () => ({
  ReactionGame: ({ onSuccess, onFail }: { onSuccess: () => void; onFail: () => void }) => (
    <div>
      <h3>Mock Reaction</h3>
      <button onClick={onSuccess}>Win Mini-game</button>
      <button onClick={onFail}>Lose Mini-game</button>
    </div>
  ),
}));

vi.mock('../../src/components/minigames/FindTheRingGame', () => ({
  FindTheRingGame: ({ onSuccess, onFail }: { onSuccess: () => void; onFail: () => void }) => (
    <div>
      <h3>Mock Find Ring</h3>
      <button onClick={onSuccess}>Win Mini-game</button>
      <button onClick={onFail}>Lose Mini-game</button>
    </div>
  ),
}));

describe('QuestCompletionModal integration', () => {
  beforeEach(() => {
    vi.useRealTimers();
    vi.spyOn(Math, 'random').mockReturnValue(0);
  });

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

  it('completes a quest only after winning and claiming reward', async () => {
    const onClose = vi.fn();
    const onComplete = vi.fn().mockResolvedValue(undefined);

    render(
      <QuestCompletionModal
        isOpen={true}
        onClose={onClose}
        onComplete={onComplete}
        questId={42}
        questTitle="Destroy the One Ring"
      />
    );

    expect(await screen.findByText('Mock Trivia')).toBeTruthy();

    fireEvent.click(screen.getByRole('button', { name: 'Win Mini-game' }));
    fireEvent.click(await screen.findByRole('button', { name: /Claim Reward/i }));

    await waitFor(() => {
      expect(onComplete).toHaveBeenCalledWith(42);
      expect(onClose).toHaveBeenCalled();
    });
  });

  it('keeps modal open and does not complete on mini-game failure', async () => {
    const onClose = vi.fn();
    const onComplete = vi.fn().mockResolvedValue(undefined);

    render(
      <QuestCompletionModal
        isOpen={true}
        onClose={onClose}
        onComplete={onComplete}
        questId={99}
        questTitle="Guard the Shire"
      />
    );

    expect(await screen.findByText('Mock Trivia')).toBeTruthy();

    fireEvent.click(screen.getByRole('button', { name: 'Lose Mini-game' }));
    expect(screen.getByText(/Resetting challenge/i)).toBeTruthy();

    await waitFor(() => {
      expect(screen.getByText('Mock Trivia')).toBeTruthy();
    }, { timeout: 1500 });

    expect(onComplete).not.toHaveBeenCalled();
    expect(onClose).not.toHaveBeenCalled();
  });
});
