import { beforeEach, describe, expect, it, vi } from 'vitest';
import { getPlayoutBlockHistory, getPlayoutBlocks, getPlayoutHistoryDetails } from './playoutHistory';

function mockJson(body: unknown, status = 200) {
  return vi.spyOn(window, 'fetch').mockResolvedValue(
    new Response(JSON.stringify(body), {
      headers: { 'Content-Type': 'application/json' },
      status
    })
  );
}

describe('getPlayoutBlocks', () => {
  beforeEach(() => {
    window.localStorage.clear();
    vi.restoreAllMocks();
  });

  it('GETs /api/v1/playouts/{id}/blocks', async () => {
    const fetchSpy = mockJson([{ id: 1, name: 'Morning' }]);

    await expect(getPlayoutBlocks(7)).resolves.toHaveLength(1);

    const [url, init] = fetchSpy.mock.calls[0];
    expect(url).toBe('/api/v1/playouts/7/blocks');
    expect((init?.method ?? 'GET').toUpperCase()).toBe('GET');
  });
});

describe('getPlayoutBlockHistory', () => {
  beforeEach(() => {
    window.localStorage.clear();
    vi.restoreAllMocks();
  });

  it('GETs history without a query string when no params are given', async () => {
    const fetchSpy = mockJson({ totalCount: 0, page: [] });

    await getPlayoutBlockHistory(7, 3);

    const [url] = fetchSpy.mock.calls[0];
    expect(url).toBe('/api/v1/playouts/7/blocks/3/history');
  });

  it('builds the query string from pageNum and pageSize', async () => {
    const fetchSpy = mockJson({ totalCount: 0, page: [] });

    await getPlayoutBlockHistory(7, 3, { pageNum: 2, pageSize: 25 });

    const [url] = fetchSpy.mock.calls[0];
    expect(url).toBe('/api/v1/playouts/7/blocks/3/history?pageNum=2&pageSize=25');
  });
});

describe('getPlayoutHistoryDetails', () => {
  beforeEach(() => {
    window.localStorage.clear();
    vi.restoreAllMocks();
  });

  it('GETs /api/v1/playouts/history/{id}', async () => {
    const fetchSpy = mockJson({
      playbackOrder: 'Shuffle',
      collectionType: 'Collection',
      name: 'Cartoons',
      mediaItemType: 'Episode',
      mediaItemTitle: 'S1E1'
    });

    await expect(getPlayoutHistoryDetails(42)).resolves.toMatchObject({ name: 'Cartoons' });

    const [url] = fetchSpy.mock.calls[0];
    expect(url).toBe('/api/v1/playouts/history/42');
  });

  it('rejects with the ApiError status on failure', async () => {
    mockJson({ status: 422, title: 'Validation failed' }, 422);

    await expect(getPlayoutHistoryDetails(42)).rejects.toMatchObject({ status: 422 });
  });
});
