import type { Did } from "@atcute/lexicons/syntax";
import { createBobbinClient } from "$lib/api/client";
import { count } from "$lib/api/count";
import { toHttpError } from "$lib/api/load";
import {
	fetchReposPage,
	fetchStringsPage,
	fetchStarredPage,
	fetchPeoplePage,
	fetchVouchesPage,
	fetchPinned
} from "$lib/components/profile/pages";
import type { PageLoad } from "./$types";

const TABS = [
	"overview",
	"repos",
	"starred",
	"strings",
	"followers",
	"following",
	"vouches"
] as const;
type Tab = (typeof TABS)[number];

const normalizeTab = (raw: string | null): Tab =>
	TABS.includes(raw as Tab) ? (raw as Tab) : "overview";

export const load: PageLoad = async (event) => {
	const parent = await event.parent();
	const tab = normalizeTab(event.url.searchParams.get("tab"));

	if (parent.notJoined) return { tab: "overview" as const, overview: { pinned: [] } };

	const ctx = createBobbinClient({ serviceUrl: parent.publicConfig.bobbinUrl, fetch: event.fetch });
	const did = parent.identity.did as Did;
	const handle = parent.identity.handle;
	const viewerDid = parent.auth?.did;

	try {
		switch (tab) {
			case "repos": {
				const q = event.url.searchParams.get("q")?.trim();
				const page = await fetchReposPage(ctx, { did, handle, viewerDid, q: q || undefined });
				return { tab: "repos" as const, repos: page.items, cursor: page.cursor };
			}
			case "strings": {
				const page = await fetchStringsPage(ctx, { did, handle });
				return { tab: "strings" as const, strings: page.items, cursor: page.cursor };
			}
			case "followers":
			case "following": {
				const page = await fetchPeoplePage(ctx, { did, viewerDid, direction: tab });
				return { tab, people: page.items, cursor: page.cursor } as const;
			}
			case "vouches": {
				const page = await fetchVouchesPage(ctx, { did });
				const outgoing = await count(ctx, "sh.tangled.graph.countVouchesBy", did);
				return {
					tab: "vouches" as const,
					vouches: page.items,
					cursors: page.cursors,
					vouchTotal: parent.counts.vouches + outgoing.count,
					isSelf: viewerDid === did,
					profileHandle: handle
				};
			}
			case "starred": {
				const page = await fetchStarredPage(ctx, { did, viewerDid });
				return { tab: "starred" as const, stars: page.items, cursor: page.cursor };
			}
			case "overview":
			default: {
				const pinned = await fetchPinned(ctx, {
					keys: parent.profile?.pinnedRepositories ?? [],
					handle,
					viewerDid
				});
				return { tab: "overview" as const, overview: { pinned } };
			}
		}
	} catch (cause) {
		console.error("Page load error:", cause);
		toHttpError(cause, "Could not load profile data");
	}
};
