import { error } from '@sveltejs/kit';
import { createApiClient, extractErrorCode } from '$lib/shared/api.server';
import { getErrorMessage } from '$lib/shared/errors';
import { settled } from '$lib/shared/server/settled';
import type { components } from '$lib/generated/api';
import type { PageServerLoad } from './$types';

type Person = components['schemas']['Person'];
type GeschichteSummary = components['schemas']['GeschichteSummary'];

const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

export const load: PageServerLoad = async ({ url, fetch, parent }) => {
	const { canBlogWrite } = await parent();
	const api = createApiClient(fetch);
	const personIds = url.searchParams.getAll('personId');
	const rawDocumentId = url.searchParams.get('documentId');
	const documentId = rawDocumentId && UUID_PATTERN.test(rawDocumentId) ? rawDocumentId : null;

	const [listSettled, draftsSettled, docSettled, ...personResults] = await Promise.allSettled([
		api.GET('/api/geschichten', {
			params: {
				query: {
					status: 'PUBLISHED',
					personId: personIds.length ? personIds : undefined,
					documentId: documentId ?? undefined
				}
			}
		}),
		canBlogWrite
			? api.GET('/api/geschichten', { params: { query: { status: 'DRAFT' } } })
			: Promise.resolve(null),
		documentId
			? api.GET('/api/documents/{id}', { params: { path: { id: documentId } } })
			: Promise.resolve(null),
		...personIds.map((id) => api.GET('/api/persons/{id}', { params: { path: { id } } }))
	]);

	const listResult = listSettled.status === 'fulfilled' ? listSettled.value : null;
	if (!listResult?.response.ok) {
		throw error(
			listResult?.response.status ?? 500,
			getErrorMessage(extractErrorCode(listResult?.error))
		);
	}

	const drafts: GeschichteSummary[] = canBlogWrite
		? (settled<GeschichteSummary[]>(draftsSettled) ?? [])
		: [];

	const personFilters = personResults
		.filter((r) => r.status === 'fulfilled' && r.value?.response.ok && r.value?.data)
		.map((r) => (r as PromiseFulfilledResult<{ response: Response; data: Person }>).value.data);

	const docResult = docSettled.status === 'fulfilled' ? docSettled.value : null;
	let documentFilter: { id: string; title: string | null } | null = null;
	if (documentId) {
		if (docResult && docResult.response.ok && docResult.data) {
			const doc = docResult.data;
			documentFilter = {
				id: documentId,
				title: doc.title ?? doc.originalFilename ?? null
			};
		} else {
			documentFilter = { id: documentId, title: null };
		}
	}

	return {
		geschichten: listResult.data ?? [],
		drafts,
		personFilters,
		documentFilter
	};
};
