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

export async function load({
	params,
	fetch,
	locals,
	depends
}: {
	params: { id: string };
	fetch: typeof globalThis.fetch;
	locals: App.Locals;
	depends: (dep: string) => void;
}) {
	const canWrite =
		locals.user?.groups?.some((g: { permissions: string[] }) =>
			g.permissions.includes('WRITE_ALL')
		) ?? false;
	if (!canWrite) throw redirect(303, '/');

	depends('app:document');

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

	const [docResult, countResult] = await Promise.all([
		api.GET('/api/documents/{id}', { params: { path: { id } } }),
		api.GET('/api/documents/incomplete-count')
	]);

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

	const incompleteCount = countResult.response.ok ? (countResult.data?.count ?? 0) : 0;

	return {
		document: docResult.data!,
		incompleteCount
	};
}

async function redirectToNext(id: string, fetch: typeof globalThis.fetch): Promise<never> {
	const api = createApiClient(fetch);
	const nextResult = await api.GET('/api/documents/incomplete/next', {
		params: { query: { excludeId: id } }
	});

	if (nextResult.response.ok && nextResult.data) {
		throw redirect(303, `/enrich/${nextResult.data.id}`);
	}
	throw redirect(303, '/enrich/done');
}

export const actions = {
	skip: async ({ params, fetch }: { params: { id: string }; fetch: typeof globalThis.fetch }) => {
		await redirectToNext(params.id, fetch);
	},

	save: async ({
		params,
		request,
		fetch
	}: {
		params: { id: string };
		request: Request;
		fetch: typeof globalThis.fetch;
	}) => {
		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 { error: getErrorMessage(backendError?.code) };
		}

		await redirectToNext(params.id, fetch);
	},

	saveAndReview: async ({
		params,
		request,
		fetch
	}: {
		params: { id: string };
		request: Request;
		fetch: typeof globalThis.fetch;
	}) => {
		const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
		const formData = await request.formData();
		formData.set('metadataComplete', 'true');

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

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

		await redirectToNext(params.id, fetch);
	}
};
