<script lang="ts">
	import { now as tidNow } from "@atcute/tid";
	import SmilePlus from "$icon/smile-plus";
	import { putReaction, deleteReaction } from "$lib/api/reaction";
	import { getAuth } from "$lib/auth.svelte";
	import type { ReactionRecord } from "$lib/api/records";
	import Button from "$lib/components/ui/Button.svelte";
	import { ORDERED_REACTION_KINDS, type ReactionKind } from "./reactions";

	interface Props {
		subjectUri: string;
		// kinds the viewer reacted with, mapped to their record's rkey so a repeat pick deletes it
		reacted?: Map<ReactionKind, string>;
		onreacted?: (kind: ReactionKind, rkey: string) => void;
		onunreacted?: (kind: ReactionKind) => void;
	}

	let { subjectUri, reacted, onreacted, onunreacted }: Props = $props();

	const auth = getAuth();

	const rawId = $props.id();
	const popoverId = `reaction-picker-${rawId.replace(/[^a-zA-Z0-9]/g, "")}`;
	const anchorName = `--${popoverId}`;

	let panel = $state<HTMLElement>();
	let pending = $state<ReactionKind | null>(null);

	const pick = async (kind: ReactionKind) => {
		const agent = auth?.agent;
		if (!agent || pending) return;

		pending = kind;
		try {
			const existingRkey = reacted?.get(kind);
			if (existingRkey) {
				await deleteReaction(agent, existingRkey);
				onunreacted?.(kind);
			} else {
				const rkey = tidNow();
				const record: ReactionRecord = {
					$type: "sh.tangled.feed.reaction",
					subject: subjectUri as ReactionRecord["subject"],
					reaction: kind,
					createdAt: new Date().toISOString()
				};
				await putReaction(agent, rkey, record);
				onreacted?.(kind, rkey);
			}
			panel?.hidePopover();
		} catch {
			// leave the panel open on failure so the user can retry
		} finally {
			pending = null;
		}
	};
</script>

<button
	type="button"
	popovertarget={popoverId}
	style={`anchor-name: ${anchorName}`}
	aria-label="Add reaction"
	class="py-2 flex cursor-pointer items-center justify-center rounded text-foreground-subtle transition hover:text-foreground-default"
>
	<SmilePlus class="size-3" />
</button>

<div
	bind:this={panel}
	id={popoverId}
	popover="auto"
	style={`position-anchor: ${anchorName}`}
	class="inset-auto mt-1 h-fit w-max rounded border border-border-default bg-background-default text-foreground-default shadow-menu [position-area:bottom_center]"
>
	<div class="grid grid-cols-4 p-1">
		{#each ORDERED_REACTION_KINDS as kind (kind)}
			<Button
				variant="ghost"
				size="sm"
				aria-label={`React with ${kind}`}
				aria-pressed={reacted?.has(kind) ?? false}
				disabled={pending !== null}
				onclick={() => pick(kind)}
			>
				{kind}
			</Button>
		{/each}
	</div>
</div>
