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

vi.mock('../../src/services/igdbClient', () => ({
  searchGames: vi.fn(),
  getGameById: vi.fn(),
}));

vi.mock('../../src/services/rawgClient', () => ({
  searchGames: vi.fn(),
  getGameById: vi.fn(),
}));

vi.mock('../../src/services/thegamesdbClient', () => ({
  searchGames: vi.fn(),
  getGameById: vi.fn(),
}));

import * as igdb from '../../src/services/igdbClient';
import * as rawg from '../../src/services/rawgClient';
import * as tgdb from '../../src/services/thegamesdbClient';
import { enrichGame } from '../../src/services/metadataService';

describe('services/metadataService', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('prioriza IGDB cuando hay resultados', async () => {
    (igdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([
      {
        id: 11,
        name: 'Sonic',
        slug: 'sonic',
        releaseDate: '1991-06-23',
        genres: ['Platform'],
        coverUrl: 'http://img',
        source: 'igdb',
      },
    ]);

    (rawg.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);
    (tgdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);

    const res = await enrichGame({ title: 'Sonic' });
    expect(res).not.toBeNull();
    expect(res?.source).toBe('igdb');
    expect(res?.externalIds.igdb).toBe(11);
    expect(res?.title).toBe('Sonic');
  });

  it('cae a RAWG cuando IGDB no responde resultados', async () => {
    (igdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);

    (rawg.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([
      {
        id: 22,
        name: 'Sonic (rawg)',
        slug: 'sonic-rawg',
        releaseDate: '1991-06-23',
        genres: ['Platform'],
        coverUrl: 'http://img',
        source: 'rawg',
      },
    ]);

    (tgdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);

    const res = await enrichGame({ title: 'Sonic' });
    expect(res).not.toBeNull();
    expect(res?.source).toBe('rawg');
    expect(res?.externalIds.rawg).toBe(22);
  });

  it('retorna null si no hay resultados en ninguna API', async () => {
    (igdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);
    (rawg.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);
    (tgdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);

    const res = await enrichGame({ title: 'Juego inexistente' });
    expect(res).toBeNull();
  });
});
