<script lang="ts">
import { goto } from '$app/navigation';
import { enhance } from '$app/forms';
import { m } from '$lib/paraglide/messages.js';
import { relativeTime } from '$lib/shared/utils/time';
import { buildCommentHref } from '$lib/shared/discussion/commentDeepLink';
import type { NotificationItem } from '$lib/notification/notifications.svelte';

type Props = {
	notifications: NotificationItem[];
	optimisticMarkRead: (id: string) => void;
	optimisticMarkAllRead: () => void;
	onClose: () => void;
};

let { notifications, optimisticMarkRead, optimisticMarkAllRead, onClose }: Props = $props();

let errorMessage = $state<string | null>(null);

function handleViewAll() {
	onClose(); // close first — avoids stale dropdown during navigation transition
	goto('/aktivitaeten');
}
</script>

<div
	role="dialog"
	aria-modal="true"
	aria-label={m.notification_bell_label()}
	class="absolute right-0 z-50 mt-2 w-80 overflow-hidden rounded-sm border border-line bg-surface shadow-lg"
>
	<!-- Header -->
	<div class="flex items-center justify-between border-b border-line px-4 py-3">
		<span class="text-xs font-bold tracking-widest text-ink-2 uppercase">
			{m.notification_bell_label()}
		</span>
		{#if notifications.length > 0}
			<form
				action="/aktivitaeten?/mark-all-read"
				method="POST"
				use:enhance={() => {
					errorMessage = null;
					optimisticMarkAllRead();
					return async ({ result, update }) => {
						if (result.type === 'failure' || result.type === 'error') {
							errorMessage = (result as { data?: { error?: string } }).data?.error ?? m.notification_error_generic();
							await update({ reset: false, invalidateAll: false });
						}
					};
				}}
			>
				<button
					type="submit"
					class="text-xs font-medium text-ink-3 transition-colors hover:text-ink"
				>
					{m.notification_mark_all_read()}
				</button>
			</form>
		{/if}
	</div>

	<!-- Error banner (shown when a dismiss or mark-all action fails) -->
	{#if errorMessage}
		<p role="alert" class="px-4 py-2 text-sm text-red-600">{errorMessage}</p>
	{/if}

	<!-- Notification list -->
	{#if notifications.length === 0}
		<!-- Empty state -->
		<div class="flex flex-col items-center gap-2 px-4 py-8 text-center text-sm text-ink-3">
			<svg
				xmlns="http://www.w3.org/2000/svg"
				class="h-8 w-8 text-ink-3 opacity-40"
				fill="none"
				viewBox="0 0 24 24"
				stroke="currentColor"
				stroke-width="1.5"
				aria-hidden="true"
			>
				<path
					stroke-linecap="round"
					stroke-linejoin="round"
					d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
				/>
			</svg>
			<span>{m.notification_empty()}</span>
		</div>
	{:else}
		<ul role="list" class="max-h-[24rem] overflow-y-auto">
			{#each notifications as notification (notification.id)}
				<li>
					<form
						action="/aktivitaeten?/dismiss-notification"
						method="POST"
						class="contents"
						use:enhance={() => {
							errorMessage = null;
							optimisticMarkRead(notification.id);
							return async ({ result, update }) => {
								if (result.type === 'failure' || result.type === 'error') {
									errorMessage = (result as { data?: { error?: string } }).data?.error ?? m.notification_error_generic();
									await update({ reset: false, invalidateAll: false });
								} else {
									// Navigate away — no need to update the store since we're leaving the page
									onClose();
									goto(
										buildCommentHref(
											notification.documentId,
											notification.referenceId,
											notification.annotationId
										)
									);
								}
							};
						}}
					>
						<input type="hidden" name="notificationId" value={notification.id} />
						<button
							type="submit"
							class="flex w-full cursor-pointer items-start gap-3 border-b border-line px-4 py-3.5 text-left last:border-b-0 hover:bg-canvas
								{!notification.read ? 'bg-accent-bg/20' : ''}"
						>
							<!-- Type icon -->
							<span class="mt-0.5 shrink-0 text-ink-3" aria-hidden="true">
								{#if notification.type === 'REPLY'}
									<!-- Reply icon -->
									<svg
										xmlns="http://www.w3.org/2000/svg"
										class="h-4 w-4"
										fill="none"
										viewBox="0 0 24 24"
										stroke="currentColor"
										stroke-width="2"
									>
										<path
											stroke-linecap="round"
											stroke-linejoin="round"
											d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"
										/>
									</svg>
								{:else}
									<!-- Mention icon -->
									<svg
										xmlns="http://www.w3.org/2000/svg"
										class="h-4 w-4"
										fill="none"
										viewBox="0 0 24 24"
										stroke="currentColor"
										stroke-width="2"
									>
										<path
											stroke-linecap="round"
											stroke-linejoin="round"
											d="M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207"
										/>
									</svg>
								{/if}
							</span>

							<!-- Text + time -->
							<div class="min-w-0 flex-1">
								<p class="text-sm leading-snug text-ink">
									{notification.type === 'REPLY'
										? m.notification_type_reply({ actor: notification.actorName })
										: m.notification_type_mention({ actor: notification.actorName })}
								</p>
								<p class="mt-1 text-xs text-ink-3">{relativeTime(notification.createdAt)}</p>
							</div>

							<!-- Unread dot -->
							{#if !notification.read}
								<span
									class="mt-1.5 h-2 w-2 shrink-0 rounded-full bg-primary"
									aria-label={m.notification_unread()}
								></span>
							{/if}
						</button>
					</form>
				</li>
			{/each}
		</ul>
	{/if}

	<div class="border-t border-line px-4 py-2">
		<button
			type="button"
			onclick={handleViewAll}
			class="min-h-[44px] px-1 text-xs font-medium text-ink-2 transition-colors hover:text-ink"
		>
			{m.chronik_view_all()}
		</button>
	</div>
</div>
