<script lang="ts">
	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="/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-danger">Something went wrong. Try again.</p>
			{/if}
		</div>
	{/if}
{/if}
