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';
import { actions } from './+page.server';

const mockFetch = vi.fn() as unknown as typeof fetch;

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

function buildRequest(overrides: Partial<Record<string, string>> = {}): Request {
	const fd = new FormData();
	fd.set('personType', 'PERSON');
	fd.set('firstName', 'Hans');
	fd.set('lastName', 'Müller');
	for (const [k, v] of Object.entries(overrides)) {
		if (v == null) fd.delete(k);
		else fd.set(k, v);
	}
	return new Request('http://localhost/persons/new', { method: 'POST', body: fd });
}

describe('persons/new create action — generation (#689)', () => {
	it('always includes generation in the POST body — even when value is 0', async () => {
		const post = vi
			.fn()
			.mockResolvedValue({ response: { ok: true, status: 200 }, data: { id: 'p-new' } });
		vi.mocked(createApiClient).mockReturnValue({ POST: post } as unknown as ReturnType<
			typeof createApiClient
		>);

		const request = buildRequest({ generation: '0' });

		try {
			// eslint-disable-next-line @typescript-eslint/no-explicit-any
			await actions.default({ request, fetch: mockFetch } as any);
		} catch {
			// redirect throws on success — ignore
		}

		expect(post).toHaveBeenCalledTimes(1);
		const body = post.mock.calls[0][1].body;
		expect(body).toHaveProperty('generation', 0);
	});

	it('sends generation: null when the dropdown is left unset', async () => {
		const post = vi
			.fn()
			.mockResolvedValue({ response: { ok: true, status: 200 }, data: { id: 'p-new' } });
		vi.mocked(createApiClient).mockReturnValue({ POST: post } as unknown as ReturnType<
			typeof createApiClient
		>);

		const request = buildRequest({ generation: '' });

		try {
			// eslint-disable-next-line @typescript-eslint/no-explicit-any
			await actions.default({ request, fetch: mockFetch } as any);
		} catch {
			// redirect throws on success — ignore
		}

		expect(post).toHaveBeenCalledTimes(1);
		const body = post.mock.calls[0][1].body;
		expect(body).toHaveProperty('generation', null);
	});
});
