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

vi.mock('$lib/shared/api.server', () => ({
	createApiClient: vi.fn(),
	extractErrorCode: (e: unknown) => (e as { code?: string } | undefined)?.code
}));

import { createApiClient } from '$lib/shared/api.server';

beforeEach(() => vi.clearAllMocks());

function mockApiGet(ok: boolean, data: unknown) {
	vi.mocked(createApiClient).mockReturnValue({
		GET: vi.fn().mockResolvedValue({ response: { ok }, data })
	} as ReturnType<typeof createApiClient>);
}

const makeTag = (name: string, documentCount = 0) => ({
	id: 'id-' + name,
	name,
	documentCount,
	children: []
});

describe('/themen +page.server load', () => {
	function makeLoadEvent() {
		return {
			fetch: vi.fn() as unknown as typeof fetch,
			request: new Request('http://localhost/themen'),
			url: new URL('http://localhost/themen')
		};
	}

	it('returns tag tree when API succeeds', async () => {
		const tree = [makeTag('Briefe', 5), makeTag('Fotos', 3)];
		mockApiGet(true, tree);

		const { load } = await import('./+page.server');
		const result = await load(makeLoadEvent());

		expect(result.tree).toEqual(tree);
	});

	it('returns empty array when API returns empty list', async () => {
		mockApiGet(true, []);

		const { load } = await import('./+page.server');
		const result = await load(makeLoadEvent());

		expect(result.tree).toEqual([]);
	});

	it('throws 500 when API call fails', async () => {
		mockApiGet(false, null);

		const { load } = await import('./+page.server');

		await expect(load(makeLoadEvent())).rejects.toMatchObject({ status: 500 });
	});
});
