<script lang="ts">
	import { resolve } from "$app/paths";
	import Button from "$lib/components/ui/Button.svelte";
	import UserRoundPlus from "$icon/user-round-plus";
	import UserRoundMinus from "$icon/user-round-minus";
	import { getAuth } from "$lib/auth.svelte";
	import { createFollow, deleteFollow } from "$lib/api/graph";
	import { getProfileCounts } from "./counts.svelte";
	import type { FollowChange } from "./types";
	import { createOptimisticRelation } from "$lib/optimistic.svelte";

	interface Props {
		profileDid: string;
		initialRkey?: string | null;
		size?: "sm" | "md";
		onCommit?: (change: FollowChange) => void;
	}

	let { profileDid, initialRkey, size = "sm", onCommit }: Props = $props();

	const auth = getAuth();
	const profileCounts = getProfileCounts();
	const signedIn = $derived(Boolean(auth.currentDid));
	const isSelf = $derived(auth.currentDid === profileDid);
	const relation = createOptimisticRelation({
		key: () => `${auth.currentDid ?? ""}:${profileDid}`,
		loadedRkey: () => initialRkey
	});

	let busy = $state(false);
	const following = $derived(relation.active);

	const commit = (change: FollowChange) => {
		profileCounts?.adjust(change.subjectDid, "followers", change.delta);
		profileCounts?.adjust(change.viewerDid, "following", change.delta);
		onCommit?.(change);
	};

	const toggle = async () => {
		const agent = auth.agent;
		if (!agent || busy || !relation.known) return;
		busy = true;
		relation.resetFailure();
		try {
			if (relation.active && relation.rkey) {
				await deleteFollow(agent, relation.rkey);
				relation.deleted();
				commit({
					viewerDid: agent.sub,
					subjectDid: profileDid,
					following: false,
					rkey: null,
					delta: -1
				});
			} else {
				const rkey = await createFollow(agent, profileDid);
				relation.created(rkey);
				commit({
					viewerDid: agent.sub,
					subjectDid: profileDid,
					following: true,
					rkey,
					delta: 1
				});
			}
		} catch {
			relation.fail();
		} finally {
			busy = false;
		}
	};
</script>

{#if !isSelf}
	{#if !signedIn}
		<Button href={resolve("/login")} variant="default" {size} class="w-full gap-2">
			<UserRoundPlus class="size-4" aria-hidden="true" /><span>Follow</span>
		</Button>
	{:else}
		<div class="w-full">
			<Button
				variant="default"
				{size}
				class="w-full gap-2"
				loading={busy}
				disabled={!relation.known}
				onclick={toggle}
			>
				{#if following}
					<UserRoundMinus class="size-4" aria-hidden="true" />
				{:else}
					<UserRoundPlus class="size-4" aria-hidden="true" />
				{/if}
				<span>{following ? "Unfollow" : "Follow"}</span>
			</Button>
			{#if relation.failed}
				<p class="mt-1 text-xs text-foreground-danger">Something went wrong. Try again.</p>
			{/if}
		</div>
	{/if}
{/if}
