import { afterEach, describe, expect, it, vi } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page, userEvent } from 'vitest/browser';
import { m } from '$lib/paraglide/messages.js';
import { getErrorMessage } from '$lib/shared/errors';

vi.mock('$app/navigation', () => ({
	goto: vi.fn()
}));

const { default: JourneyCreate } = await import('./JourneyCreate.svelte');

afterEach(() => {
	cleanup();
	vi.unstubAllGlobals();
});

describe('JourneyCreate — failure path', () => {
	it('renders the mapped error message when POST /api/geschichten fails with a code', async () => {
		vi.stubGlobal(
			'fetch',
			vi.fn().mockResolvedValue({
				ok: false,
				json: vi.fn().mockResolvedValue({ code: 'VALIDATION_ERROR' })
			})
		);

		render(JourneyCreate, {});

		await userEvent.fill(
			page.getByRole('textbox', { name: m.journey_title_aria_label() }),
			'Meine Lesereise'
		);
		await userEvent.click(page.getByRole('button', { name: m.journey_create_submit() }));

		const alert = page.getByRole('alert');
		await expect.element(alert).toBeInTheDocument();
		await expect.element(alert).toHaveTextContent(getErrorMessage('VALIDATION_ERROR'));
	});

	it('navigates to the edit page on success', async () => {
		const { goto } = await import('$app/navigation');
		vi.mocked(goto).mockClear();
		vi.stubGlobal(
			'fetch',
			vi.fn().mockResolvedValue({
				ok: true,
				json: vi.fn().mockResolvedValue({ id: 'g-new' })
			})
		);

		render(JourneyCreate, {});

		await userEvent.fill(
			page.getByRole('textbox', { name: m.journey_title_aria_label() }),
			'Meine Lesereise'
		);
		await userEvent.click(page.getByRole('button', { name: m.journey_create_submit() }));

		await vi.waitFor(() => {
			expect(goto).toHaveBeenCalledWith('/geschichten/g-new/edit');
		});
	});

	it('shows an error alert when the network request rejects (no crash)', async () => {
		vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new TypeError('network down')));
		const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});

		render(JourneyCreate, {});

		await userEvent.fill(
			page.getByRole('textbox', { name: m.journey_title_aria_label() }),
			'Meine Lesereise'
		);
		await userEvent.click(page.getByRole('button', { name: m.journey_create_submit() }));

		await expect.element(page.getByRole('alert')).toBeInTheDocument();
		consoleError.mockRestore();
	});

	it('has an accessible label on the title input', async () => {
		vi.stubGlobal('fetch', vi.fn());
		render(JourneyCreate, {});

		await expect
			.element(page.getByRole('textbox', { name: m.journey_title_aria_label() }))
			.toBeInTheDocument();
	});
});
