<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/state';
import { m } from '$lib/paraglide/messages.js';
import { relativeTime, type NotificationItem } from '$lib/utils/notifications';

let { data } = $props();

let additionalNotifications = $state<NotificationItem[]>([]);
let loadMorePage = $state(1);
let isLoadingMore = $state(false);

const allNotifications = $derived([...data.notifications, ...additionalNotifications]);
const activeType = $derived(page.url.searchParams.get('type'));
const activeReadFilter = $derived(page.url.searchParams.get('read'));
const hasMore = $derived(loadMorePage < (data.totalPages ?? 1));

function setFilter(params: Record<string, string | null>) {
	additionalNotifications = [];
	loadMorePage = 1;
	const url = new URL(page.url);
	for (const [k, v] of Object.entries(params)) {
		if (v === null) url.searchParams.delete(k);
		else url.searchParams.set(k, v);
	}
	goto(url.toString());
}

async function loadMore() {
	isLoadingMore = true;
	try {
		const typeParam = page.url.searchParams.get('type');
		const readParam = page.url.searchParams.get('read');
		let query = `page=${loadMorePage}&size=20`;
		if (typeParam) query += `&type=${typeParam}`;
		if (readParam !== null) query += `&read=${readParam}`;
		const res = await fetch(`/api/notifications?${query}`);
		if (res.ok) {
			const json = await res.json();
			additionalNotifications = [...additionalNotifications, ...(json.content ?? [])];
			loadMorePage += 1;
		}
	} finally {
		isLoadingMore = false;
	}
}

async function navigateToNotification(n: NotificationItem) {
	if (!n.read) {
		await fetch(`/api/notifications/${n.id}/read`, { method: 'PATCH' });
	}
	const url = n.annotationId
		? `/documents/${n.documentId}?commentId=${n.referenceId}&annotationId=${n.annotationId}`
		: `/documents/${n.documentId}?commentId=${n.referenceId}`;
	goto(url);
}

function typeBadgeLabel(type: NotificationItem['type']): string {
	return type === 'MENTION' ? m.notification_filter_mention() : m.notification_filter_reply();
}
</script>

<svelte:head>
	<title>{m.notification_history_heading()}</title>
</svelte:head>

<div class="min-h-screen bg-canvas">
	<div class="mx-auto max-w-2xl px-4 py-8 sm:px-6 lg:px-8">
		<!-- Back link -->
		<a
			href="/"
			class="group mb-4 inline-flex items-center text-xs font-bold tracking-widest text-gray-500 uppercase transition-colors hover:text-ink"
		>
			<svg
				class="mr-2 h-4 w-4 transform transition-transform group-hover:-translate-x-1"
				xmlns="http://www.w3.org/2000/svg"
				fill="none"
				viewBox="0 0 24 24"
				stroke-width="2"
				stroke="currentColor"
				aria-hidden="true"
			>
				<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
			</svg>
			{m.btn_back_to_overview()}
		</a>

		<!-- Page header -->
		<div class="mb-6 flex items-center justify-between">
			<h1 class="font-serif text-2xl font-medium text-ink">
				{m.notification_history_heading()}
			</h1>
			{#if data.unreadCount > 0}
				<form method="POST" action="?/mark-all">
					<button
						type="submit"
						class="text-sm font-medium text-ink-2 transition-colors hover:text-ink"
						aria-label={m.notification_mark_all_read_aria()}
					>
						{m.notification_mark_all_read()}
					</button>
				</form>
			{/if}
		</div>

		<!-- Filter pills -->
		<div role="radiogroup" aria-label="Filter" class="mb-6 flex flex-wrap gap-2">
			<!-- All -->
			<button
				role="radio"
				aria-checked={activeType === null && activeReadFilter === null}
				onclick={() => setFilter({ type: null, read: null })}
				class={[
					'rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2',
					activeType === null && activeReadFilter === null
						? 'bg-primary text-primary-fg'
						: 'bg-muted text-ink'
				].join(' ')}
			>
				{m.notification_filter_all()}
			</button>

			<!-- Unread -->
			<button
				role="radio"
				aria-checked={activeReadFilter === 'false'}
				onclick={() => setFilter({ read: 'false', type: null })}
				class={[
					'inline-flex items-center gap-1.5 rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2',
					activeReadFilter === 'false'
						? 'bg-primary text-primary-fg'
						: 'bg-muted text-ink'
				].join(' ')}
			>
				{m.notification_filter_unread()}
				{#if data.unreadCount > 0 && activeType === null && activeReadFilter === null}
					<span
						class="inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-accent px-1 font-sans text-xs font-bold text-ink"
						aria-hidden="true"
					>
						{data.unreadCount}
					</span>
				{/if}
			</button>

			<!-- Mention -->
			<button
				role="radio"
				aria-checked={activeType === 'MENTION'}
				onclick={() => setFilter({ type: 'MENTION', read: null })}
				class={[
					'rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2',
					activeType === 'MENTION'
						? 'bg-primary text-primary-fg'
						: 'bg-muted text-ink'
				].join(' ')}
			>
				{m.notification_filter_mention()}
			</button>

			<!-- Reply -->
			<button
				role="radio"
				aria-checked={activeType === 'REPLY'}
				onclick={() => setFilter({ type: 'REPLY', read: null })}
				class={[
					'rounded-full px-3 py-2 font-sans text-sm font-medium focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2',
					activeType === 'REPLY'
						? 'bg-primary text-primary-fg'
						: 'bg-muted text-ink'
				].join(' ')}
			>
				{m.notification_filter_reply()}
			</button>
		</div>

		<!-- Notification list or empty state -->
		{#if allNotifications.length === 0}
			<div class="flex flex-col items-center gap-3 py-20 text-center">
				<svg
					class="h-10 w-10 text-ink-3"
					xmlns="http://www.w3.org/2000/svg"
					fill="none"
					viewBox="0 0 24 24"
					stroke-width="1.5"
					stroke="currentColor"
					aria-hidden="true"
				>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0"
					/>
				</svg>
				<h2 class="font-serif text-lg font-semibold text-ink">
					{m.notification_empty_history()}
				</h2>
				<p class="max-w-xs font-sans text-sm text-ink-2">
					{m.notification_empty_history_body()}
				</p>
			</div>
		{:else}
			<ul
				role="list"
				class="divide-y divide-line rounded-sm border border-line bg-canvas shadow-sm"
			>
				{#each allNotifications as n (n.id)}
					<li class="relative bg-surface">
						<a
							href="/documents/{n.documentId}"
							role="row"
							class={[
								'flex min-h-14 flex-col justify-center border-l-[3px] px-4 py-4 md:px-6 md:py-5',
								'transition-colors hover:bg-accent-bg',
								n.read
									? 'border-l-transparent'
									: 'border-l-accent'
							].join(' ')}
							aria-label={m.notification_row_aria({
								actor: n.actorName,
								type: typeBadgeLabel(n.type),
								title: n.documentTitle ?? '',
								time: relativeTime(n.createdAt),
								readState: n.read ? m.notification_read_state_read() : m.notification_read_state_unread()
							})}
							onclick={(e) => {
								e.preventDefault();
								navigateToNotification(n);
							}}
						>
							<!-- Unread dot indicator -->
							{#if !n.read}
								<span
									class="absolute top-4 right-4 h-2 w-2 rounded-full bg-accent md:right-6"
									aria-hidden="true"
								></span>
							{/if}

							<!-- Line 1: actor name + type badge -->
							<div class="flex items-center gap-2">
								<span class="font-serif font-semibold text-ink">{n.actorName}</span>
								<span
									class="rounded-sm bg-muted px-2 py-0.5 font-sans text-xs tracking-wide text-ink-2 uppercase"
								>
									{typeBadgeLabel(n.type)}
								</span>
							</div>

							<!-- Line 2: document title -->
							{#if n.documentTitle}
								<p
									class="mt-0.5 font-serif text-sm text-ink hover:underline hover:decoration-accent"
								>
									{n.documentTitle}
								</p>
							{/if}

							<!-- Line 3: relative time -->
							<p class="mt-1 font-sans text-sm text-ink-3">
								{relativeTime(n.createdAt)}
							</p>
						</a>
					</li>
				{/each}
			</ul>
		{/if}

		<!-- Load more -->
		{#if hasMore}
			<button
				onclick={loadMore}
				disabled={isLoadingMore}
				class="mt-6 w-full rounded-sm border border-line py-3 text-sm font-medium text-ink-2 transition-colors hover:bg-canvas disabled:opacity-50"
			>
				{isLoadingMore ? '…' : m.notification_load_more()}
			</button>
		{/if}
	</div>
</div>
