import { afterEach, describe, expect, it, vi } from 'vitest';
import { getArtist, getMediaItemInfo, getMovie, getSeason, getShow } from './mediaDetail';

function jsonResponse(body: unknown, status = 200): Response {
  return new Response(JSON.stringify(body), { headers: { 'Content-Type': 'application/json' }, status });
}

function calledPath(fetchMock: ReturnType<typeof vi.spyOn>): string {
  return new URL(String(fetchMock.mock.calls[0][0]), 'http://localhost').pathname;
}

describe('media detail clients', () => {
  afterEach(() => {
    vi.restoreAllMocks();
  });

  it('requests the right detail routes', async () => {
    const cases: Array<[() => Promise<unknown>, string]> = [
      [() => getMovie(5), '/api/v1/movies/5'],
      [() => getShow(6), '/api/v1/shows/6'],
      [() => getSeason(7), '/api/v1/seasons/7'],
      [() => getArtist(8), '/api/v1/artists/8'],
      [() => getMediaItemInfo(9), '/api/v1/media-items/9/info']
    ];

    for (const [call, path] of cases) {
      const fetchMock = vi.spyOn(window, 'fetch').mockResolvedValue(jsonResponse({}));
      await call();
      expect(calledPath(fetchMock)).toBe(path);
      vi.restoreAllMocks();
    }
  });

  it('returns the parsed body', async () => {
    vi.spyOn(window, 'fetch').mockResolvedValue(jsonResponse({ id: 5, title: 'The Movie', poster: '/artwork/posters/x.jpg' }));
    const movie = await getMovie(5);
    expect(movie.title).toBe('The Movie');
    expect(movie.poster).toBe('/artwork/posters/x.jpg');
  });
});
