import { error } from "@sveltejs/kit";
import { createBobbinClient } from "$lib/api/client";
import { IdentityCache } from "$lib/api/identity";
import { getIssue, listComments, listIssueStates } from "$lib/api/records";
import { didFromUri, rkeyFromUri } from "$lib/api/uri";
import { renderMarkup } from "$lib/markup";
import { buildCommentThreads, type ThreadInput } from "$lib/components/comment/comments";
import type { PageLoad } from "./$types";

export const load: PageLoad = async (event) => {
	const parent = await event.parent();
	const uri = decodeURIComponent(event.params.aturi);

	if (!uri.startsWith("at://")) error(404, "Issue not found");

	const ctx = createBobbinClient({ serviceUrl: parent.publicConfig.bobbinUrl, fetch: event.fetch });

	const record = await getIssue(ctx, uri).catch(() => null);
	if (!record) error(404, "Issue not found");

	const authorDid = didFromUri(record.uri);
	const identities = new IdentityCache(ctx);
	const markupOpts = {
		repo: `${parent.repo.ownerHandle}/${parent.repo.name}`,
		ref: parent.repo.defaultBranch,
		host: event.url.host
	};

	const [author, states, comments] = await Promise.all([
		identities.resolve(authorDid).catch(() => null),
		listIssueStates(ctx, record.uri, { limit: 1, order: "desc" }).catch(() => null),
		listComments(ctx, record.uri, { order: "asc", limit: 100 }).catch(() => null)
	]);

	const latest = states?.items[0]?.value.state;
	const state = latest?.endsWith(".closed") ? ("closed" as const) : ("open" as const);

	const body = record.value.body ?? "";
	const bodyHtml = body ? await renderMarkup(body, markupOpts) : null;

	const commentItems = comments?.items ?? [];
	const threadInputs: ThreadInput[] = await Promise.all(
		commentItems.map(async (item): Promise<ThreadInput> => {
			const commentDid = didFromUri(item.uri);
			const commentBody = item.value.body?.text ?? "";
			const [doc, commentBodyHtml] = await Promise.all([
				identities.resolve(commentDid).catch(() => null),
				commentBody ? renderMarkup(commentBody, markupOpts) : Promise.resolve(null)
			]);
			return {
				comment: {
					uri: item.uri,
					cid: item.cid,
					rkey: rkeyFromUri(item.uri),
					authorDid: commentDid,
					authorHandle: doc?.handle ?? commentDid,
					createdAt: item.value.createdAt,
					body: commentBody,
					bodyHtml: commentBodyHtml
				},
				replyTo: item.value.replyTo?.uri ?? null,
				replyToCid: item.value.replyTo?.cid
			};
		})
	);

	return {
		issue: {
			uri: record.uri,
			cid: record.cid,
			rkey: rkeyFromUri(record.uri),
			title: record.value.title,
			body,
			bodyHtml,
			state,
			authorDid,
			authorHandle: author?.handle ?? authorDid,
			createdAt: record.value.createdAt
		},
		comments: buildCommentThreads(threadInputs),
		markup: markupOpts
	};
};
