import { createBobbinClient } from "$lib/api/client";
import { count } from "$lib/api/count";
import { enrich, miniDocOf, TYPE_MINIDOC } from "$lib/api/enrich";
import { IdentityCache } from "$lib/api/identity";
import type { IssueListPage } from "$lib/api/records";
import { didFromUri, rkeyFromUri } from "$lib/api/uri";
import type { IssueSummary } from "$lib/components/repo/types";
import type { PageLoad } from "./$types";

export const load: PageLoad = async (event) => {
	const parent = await event.parent();
	const state = event.url.searchParams.get("state") === "closed" ? "closed" : "open";
	const repoDid = parent.repo.repoDid;

	// no repoDid means bobbin never indexed this repo, so there is nothing to list
	if (!repoDid) {
		return {
			state: state as "open" | "closed",
			issues: [] as IssueSummary[],
			openCount: parent.counts.issues,
			closedCount: 0
		};
	}

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

	const [page, closed] = await Promise.all([
		enrich<IssueListPage>(ctx, {
			xrpc: "sh.tangled.repo.listIssues",
			params: { subject: repoDid, state },
			enrich: [
				{
					source: "sh.tangled.repo.issue:.repo",
					type: TYPE_MINIDOC,
					targets: ["items[].uri"]
				}
			]
		}),
		// the layout only knows the open count, the closed tab needs its own
		count(ctx, "sh.tangled.repo.countIssues", repoDid, { state: "closed" }).catch(() => null)
	]);

	const identity = new IdentityCache(ctx);
	const issues: IssueSummary[] = await Promise.all(
		page.output.items.map(async (item): Promise<IssueSummary> => {
			const authorDid = didFromUri(item.uri);
			const author =
				miniDocOf(page.data, authorDid, "sh.tangled.repo.issue:.repo") ??
				(await identity.resolve(authorDid).catch(() => null));
			return {
				uri: item.uri,
				rkey: rkeyFromUri(item.uri),
				title: item.value.title,
				state: item.state === "closed" ? "closed" : "open",
				authorDid,
				authorHandle: author?.handle ?? authorDid,
				createdAt: item.value.createdAt,
				commentCount: item.commentCount
			};
		})
	);

	return {
		state: state as "open" | "closed",
		issues,
		openCount: parent.counts.issues,
		closedCount: closed?.count ?? 0
	};
};
