<script lang="ts">
	import { untrack } from "svelte";
	import { getAuth } from "$lib/auth.svelte";
	import { createBobbinClient } from "$lib/api/client";
	import { IdentityCache } from "$lib/api/identity";
	import { fetchPeoplePage } from "../pages";
	import FollowCard from "../FollowCard.svelte";
	import Section from "$lib/components/ui/Section.svelte";
	import LoadMore from "$lib/components/ui/LoadMore.svelte";
	import type { PersonData } from "../types";

	interface Props {
		initial: PersonData[];
		cursor?: string;
		did: string;
		direction: "followers" | "following";
		title: string;
		emptyMessage: string;
	}

	let { initial, cursor: initialCursor, did, direction, title, emptyMessage }: Props = $props();

	const auth = getAuth();

	let extra = $state<PersonData[]>([]);
	let cursor = $state(untrack(() => initialCursor));
	let loading = $state(false);
	let failed = $state(false);
	// shared across pages so repeat dids only resolve once
	let identityCache: IdentityCache | undefined;

	const people = $derived([...initial, ...extra]);

	const loadMore = async () => {
		if (loading || !cursor) return;
		loading = true;
		failed = false;
		try {
			const ctx = createBobbinClient({ serviceUrl: auth.bobbinUrl });
			identityCache ??= new IdentityCache(ctx);
			const next = await fetchPeoplePage(ctx, {
				did,
				viewerDid: auth.currentDid ?? undefined,
				direction,
				cursor,
				cache: identityCache
			});
			extra = [...extra, ...next.items];
			cursor = next.cursor;
		} catch {
			failed = true;
		} finally {
			loading = false;
		}
	};
</script>

<Section {title} empty={people.length === 0} {emptyMessage} listClass="flex flex-col gap-8">
	{#each people as person (person.did)}
		<FollowCard {person} />
	{/each}
	{#if cursor}
		<LoadMore {loading} {failed} onclick={loadMore} />
	{/if}
</Section>
