<script lang="ts">
	import { now as tidNow } from "@atcute/tid";
	import SmilePlus from "$icon/smile-plus";
	import { createAction } from "$lib/action.svelte";
	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>();

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

		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();
	});

	const handlePick = (kind: ReactionKind) => {
		if (!pick.loading) void pick.run(kind);
	};
</script>

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

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