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

export async function load({
	params,
	fetch,
	locals,
	depends
}: {
	params: { id: string };
	fetch: typeof globalThis.fetch;
	locals: App.Locals;
	depends: (dep: string) => void;
}) {
	depends('app:document');
	if (!hasWriteAll(locals)) throw error(403, 'Forbidden');

	const { id } = params;
	const api = createApiClient(fetch);

	const docResult = await api.GET('/api/documents/{id}', { params: { path: { id } } });

	if (!docResult.response.ok) {
		throw error(docResult.response.status, getErrorMessage(extractErrorCode(docResult.error)));
	}

	return {
		document: docResult.data!,
		// Sender/receiver editing uses PersonTypeahead (self-fetching); no full list is consumed.
		persons: [] as never[]
	};
}

export const actions = {
	update: async ({ request, params, fetch }) => {
		// Raw fetch is used here because FormData multipart bodies are passed through
		// directly from the browser without transformation.
		const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
		const formData = await request.formData();

		const res = await fetch(`${baseUrl}/api/documents/${params.id}`, {
			method: 'PUT',
			body: formData
		});

		if (!res.ok) {
			const backendError = await parseBackendError(res);
			return fail(res.status, { error: getErrorMessage(backendError?.code) });
		}

		throw redirect(303, `/documents/${params.id}`);
	},

	markForReview: async ({
		params,
		fetch
	}: {
		params: { id: string };
		fetch: typeof globalThis.fetch;
	}) => {
		const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
		const api = createApiClient(fetch);

		// Fetch current document to preserve all existing fields
		const docResult = await api.GET('/api/documents/{id}', { params: { path: { id: params.id } } });
		if (!docResult.response.ok) {
			return fail(docResult.response.status, {
				error: getErrorMessage(extractErrorCode(docResult.error))
			});
		}

		const doc = docResult.data!;
		const formData = new FormData();
		if (doc.title) formData.set('title', doc.title);
		if (doc.documentDate) formData.set('documentDate', doc.documentDate);
		if (doc.location) formData.set('location', doc.location);
		if (doc.archiveBox) formData.set('archiveBox', doc.archiveBox);
		if (doc.archiveFolder) formData.set('archiveFolder', doc.archiveFolder);
		if (doc.transcription) formData.set('transcription', doc.transcription);
		if (doc.summary) formData.set('summary', doc.summary);
		if (doc.sender?.id) formData.set('senderId', doc.sender.id);
		if (doc.receivers?.length) {
			doc.receivers.forEach((r: { id: string }) => formData.append('receiverIds', r.id));
		}
		if (doc.tags?.length) {
			formData.set('tags', doc.tags.map((t: { name: string }) => t.name).join(','));
		}
		formData.set('metadataComplete', 'false');

		const res = await fetch(`${baseUrl}/api/documents/${params.id}`, {
			method: 'PUT',
			body: formData
		});

		if (!res.ok) {
			const backendError = await parseBackendError(res);
			return fail(res.status, { error: getErrorMessage(backendError?.code) });
		}

		throw redirect(303, `/documents/${params.id}`);
	},

	delete: async ({ params, fetch }) => {
		const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';

		const res = await fetch(`${baseUrl}/api/documents/${params.id}`, {
			method: 'DELETE'
		});

		if (!res.ok) {
			const backendError = await parseBackendError(res);
			return fail(res.status, { error: getErrorMessage(backendError?.code) });
		}

		throw redirect(303, '/');
	}
};
