import { fail, redirect } from '@sveltejs/kit';
import { createApiClient, extractErrorCode } from '$lib/shared/api.server';
import { getErrorMessage } from '$lib/shared/errors';
import { requireWriteAll } from '$lib/shared/server/permissions';
import {
	parseEventForm,
	validateEventForm,
	preservedFormFields,
	lookupSelections,
	toEventRequest,
	resolveNavTarget
} from '$lib/timeline/eventFormServer';
import type { PersonOption } from '$lib/person/personOption';
import type { DocumentOption } from '$lib/document/documentTypeahead';

export async function load({
	locals,
	url,
	fetch
}: {
	locals: App.Locals;
	url: URL;
	fetch: typeof globalThis.fetch;
}) {
	requireWriteAll(locals);

	const api = createApiClient(fetch);
	const personId = url.searchParams.get('personId');
	const documentId = url.searchParams.get('documentId');

	const [personResult, documentResult] = await Promise.all([
		personId ? api.GET('/api/persons/{id}', { params: { path: { id: personId } } }) : null,
		documentId ? api.GET('/api/documents/{id}', { params: { path: { id: documentId } } }) : null
	]);

	// Silently ignore 404/403 on prefill lookups to avoid leaking entity existence.
	const initialPersons: PersonOption[] =
		personResult && personResult.response.ok && personResult.data ? [personResult.data] : [];
	const initialDocuments: DocumentOption[] =
		documentResult && documentResult.response.ok && documentResult.data
			? [
					{
						id: documentResult.data.id,
						title: documentResult.data.title,
						documentDate: documentResult.data.documentDate,
						metaDatePrecision: documentResult.data.metaDatePrecision,
						metaDateEnd: documentResult.data.metaDateEnd
					}
				]
			: [];

	return { initialPersons, initialDocuments, originPersonId: personId ?? '' };
}

export const actions = {
	save: async ({ request, fetch }: { request: Request; fetch: typeof globalThis.fetch }) => {
		const parsed = parseEventForm(await request.formData());
		const api = createApiClient(fetch);

		const errors = validateEventForm(parsed);
		if (errors) {
			const { persons, documents } = await lookupSelections(
				api,
				parsed.personIds,
				parsed.documentIds
			);
			return fail(400, { ...errors, ...preservedFormFields(parsed), persons, documents });
		}

		const result = await api.POST('/api/timeline/events', { body: toEventRequest(parsed) });

		if (!result.response.ok) {
			return fail(result.response.status, {
				error: getErrorMessage(extractErrorCode(result.error)),
				...preservedFormFields(parsed)
			});
		}

		throw redirect(303, resolveNavTarget(parsed.originPersonId));
	}
};
