<script lang="ts">
	import Star from "$icon/star";
	import { getAuth } from "$lib/auth.svelte";
	import { createStar, deleteStar } from "$lib/api/graph";
	import Button from "$lib/components/ui/Button.svelte";
	import ButtonGroup from "$lib/components/ui/ButtonGroup.svelte";
	import { getProfileCounts } from "$lib/components/profile/counts.svelte";
	import { createOptimisticRelation, createOptimisticCount } from "$lib/optimistic.svelte";

	interface Props {
		repoDid: string;
		repoOwnerHandle: string;
		repoName: string;
		initialCount?: number;
		initialRkey?: string | null;
		insetShadow?: boolean;
	}

	let {
		repoDid,
		repoOwnerHandle,
		repoName,
		initialCount,
		initialRkey,
		insetShadow = true
	}: Props = $props();

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

	const starred = $derived(relation.active);
	const failed = $derived(relation.failed || starCount.failed);

	const toggle = async () => {
		const agent = auth.agent;
		if (!agent || !relation.known || relation.loading || !repoDid) return;
		relation.begin();
		starCount.resetFailure();
		try {
			if (relation.active && relation.rkey) {
				await deleteStar(agent, relation.rkey);
				relation.deleted();
				starCount.adjust(-1);
				profileCounts?.adjust(agent.sub, "stars", -1);
			} else {
				const rkey = await createStar(agent, repoDid);
				relation.created(rkey);
				starCount.adjust(1);
				profileCounts?.adjust(agent.sub, "stars", 1);
			}
		} catch {
			relation.fail();
			starCount.fail();
		}
	};
</script>

{#if signedIn && repoDid}
	<div class="flex flex-col flex-1 items-start">
		<ButtonGroup class="w-full">
			<Button
				variant="default"
				size="sm"
				{insetShadow}
				loading={relation.loading}
				disabled={!relation.known}
				onclick={toggle}
				class="flex-1"
			>
				<Star
					class={`size-4 shrink-0 ${starred ? "[&_path]:fill-[currentColor]" : ""}`}
					aria-hidden="true"
				/>
				<span>{starred ? "Unstar" : "Star"}</span>
			</Button>
			<Button
				href={`/${repoOwnerHandle}/${repoName}/stars`}
				variant="ghost"
				size="sm"
				title="Starred by"
			>
				{starCount.value}
			</Button>
		</ButtonGroup>
		{#if failed}
			<p class="mt-1 typography-paragraph-small text-foreground-danger">
				Something went wrong. Try again.
			</p>
		{/if}
	</div>
{/if}
