import { error, fail } from '@sveltejs/kit';
import { createApiClient, extractErrorCode } from '$lib/shared/api.server';
import { getErrorMessage } from '$lib/shared/errors';
import { hasWriteAll } from '$lib/shared/server/permissions';

const PAGE_SIZE = 50;

export async function load({ url, fetch, locals }) {
	const canWrite = hasWriteAll(locals);

	const page = Math.max(0, Number.parseInt(url.searchParams.get('page') ?? '0', 10) || 0);
	const api = createApiClient(fetch);

	const result = await api.GET('/api/persons', {
		params: { query: { provisional: true, review: true, page, size: PAGE_SIZE } }
	});

	if (!result.response.ok) {
		throw error(result.response.status, getErrorMessage(undefined));
	}

	const data = result.data!;

	return {
		persons: data.items,
		totalElements: data.totalElements,
		totalPages: data.totalPages,
		pageNumber: data.pageNumber,
		canWrite
	};
}

export const actions = {
	confirm: async ({ request, fetch, locals }) => {
		if (!hasWriteAll(locals)) {
			return fail(403, { error: getErrorMessage('FORBIDDEN') });
		}
		const id = (await request.formData()).get('id') as string;
		const api = createApiClient(fetch);
		const result = await api.PATCH('/api/persons/{id}/confirm', {
			params: { path: { id } }
		});
		if (!result.response.ok) {
			return fail(result.response.status, {
				error: getErrorMessage(extractErrorCode(result.error))
			});
		}
		return { success: true };
	},

	delete: async ({ request, fetch, locals }) => {
		if (!hasWriteAll(locals)) {
			return fail(403, { error: getErrorMessage('FORBIDDEN') });
		}
		const id = (await request.formData()).get('id') as string;
		const api = createApiClient(fetch);
		const result = await api.DELETE('/api/persons/{id}', {
			params: { path: { id } }
		});
		if (!result.response.ok) {
			return fail(result.response.status, {
				error: getErrorMessage(extractErrorCode(result.error))
			});
		}
		return { success: true };
	},

	merge: async ({ request, fetch, locals }) => {
		if (!hasWriteAll(locals)) {
			return fail(403, { error: getErrorMessage('FORBIDDEN') });
		}
		const formData = await request.formData();
		const id = formData.get('id') as string;
		const targetPersonId = formData.get('targetPersonId') as string;
		if (!targetPersonId) {
			return fail(400, { error: getErrorMessage('INVALID_INPUT') });
		}
		const api = createApiClient(fetch);
		const result = await api.POST('/api/persons/{id}/merge', {
			params: { path: { id } },
			body: { targetPersonId }
		});
		if (!result.response.ok) {
			return fail(result.response.status, {
				error: getErrorMessage(extractErrorCode(result.error))
			});
		}
		return { success: true };
	},

	rename: async ({ request, fetch, locals }) => {
		if (!hasWriteAll(locals)) {
			return fail(403, { error: getErrorMessage('FORBIDDEN') });
		}
		const formData = await request.formData();
		const id = formData.get('id') as string;
		const firstName = (formData.get('firstName') as string)?.trim() || undefined;
		const lastName = (formData.get('lastName') as string)?.trim();
		const personType = (formData.get('personType') as string) || 'PERSON';
		if (!lastName) {
			return fail(400, { error: getErrorMessage('INVALID_INPUT') });
		}
		const api = createApiClient(fetch);
		const result = await api.PUT('/api/persons/{id}', {
			params: { path: { id } },
			body: {
				firstName,
				lastName,
				personType: personType as 'PERSON' | 'INSTITUTION' | 'GROUP' | 'UNKNOWN'
			}
		});
		if (!result.response.ok) {
			return fail(result.response.status, {
				error: getErrorMessage(extractErrorCode(result.error))
			});
		}
		return { success: true };
	}
};
