import { describe, it, expect, vi, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';

const gotoSpy = vi.fn();
vi.mock('$app/navigation', () => ({
	beforeNavigate: () => {},
	afterNavigate: () => {},
	goto: gotoSpy,
	invalidate: vi.fn(),
	invalidateAll: vi.fn(),
	preloadCode: vi.fn(),
	preloadData: vi.fn(),
	pushState: vi.fn(),
	replaceState: vi.fn(),
	disableScrollHandling: vi.fn(),
	onNavigate: () => () => {}
}));

const { bulkSelectionStore } = await import('$lib/document/bulkSelection.svelte');
const { default: BulkEditPage } = await import('./+page.svelte');

afterEach(() => {
	cleanup();
	bulkSelectionStore.clear();
	gotoSpy.mockClear();
});

describe('documents/bulk-edit page', () => {
	it('redirects to /documents when no documents are selected', async () => {
		render(BulkEditPage, { props: {} });

		await vi.waitFor(() => expect(gotoSpy).toHaveBeenCalledWith('/documents'));
	});

	it('shows the loading spinner while fetching batch metadata', async () => {
		bulkSelectionStore.toggle('d1');
		const fetchSpy = vi.spyOn(globalThis, 'fetch').mockImplementation(() => new Promise(() => {}));
		try {
			render(BulkEditPage, { props: {} });

			await expect.element(page.getByRole('status')).toBeVisible();
			await expect.element(page.getByText('Dokumente werden geladen…')).toBeVisible();
		} finally {
			fetchSpy.mockRestore();
		}
	});

	it('shows the error banner when the fetch fails with a backend error code', async () => {
		bulkSelectionStore.toggle('d1');
		const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(
			new Response(JSON.stringify({ code: 'INTERNAL_ERROR' }), {
				status: 500,
				headers: { 'Content-Type': 'application/json' }
			})
		);
		try {
			render(BulkEditPage, { props: {} });

			await expect.element(page.getByRole('alert')).toBeVisible();
		} finally {
			fetchSpy.mockRestore();
		}
	});

	it('shows the error banner when fetch throws an unexpected error', async () => {
		bulkSelectionStore.toggle('d1');
		const fetchSpy = vi.spyOn(globalThis, 'fetch').mockRejectedValue(new Error('Network down'));
		try {
			render(BulkEditPage, { props: {} });

			await expect.element(page.getByRole('alert')).toBeVisible();
		} finally {
			fetchSpy.mockRestore();
		}
	});
});
