import { error, 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';

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

	const api = createApiClient(fetch);
	const result = await api.GET('/api/timeline/events/{id}', {
		params: { path: { id: params.id } }
	});

	// Fail closed: derived person-events (Geburt/Tod/Heirat) are not persisted and
	// have no UUID, so the API 404s for them. Any non-ok response → 404; never
	// render a blank editable form that silently POSTs a new event.
	if (!result.response.ok) throw error(404, 'Not found');

	return { event: result.data!, originPersonId: url.searchParams.get('personId') ?? '' };
}

export const actions = {
	save: async ({
		request,
		params,
		fetch
	}: {
		request: Request;
		params: { id: string };
		fetch: typeof globalThis.fetch;
	}) => {
		const formData = await request.formData();
		const parsed = parseEventForm(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 versionRaw = formData.get('version')?.toString();
		const version = versionRaw ? Number(versionRaw) : undefined;

		const result = await api.PUT('/api/timeline/events/{id}', {
			params: { path: { id: params.id } },
			body: toEventRequest(parsed, version)
		});

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

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

	delete: async ({
		request,
		params,
		fetch
	}: {
		request: Request;
		params: { id: string };
		fetch: typeof globalThis.fetch;
	}) => {
		const formData = await request.formData();
		const originPersonId = formData.get('originPersonId')?.toString() ?? '';

		const api = createApiClient(fetch);
		const result = await api.DELETE('/api/timeline/events/{id}', {
			params: { path: { id: params.id } }
		});

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

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