<script lang="ts">
	import { goto } from '$app/navigation';
	import { client } from '$lib/graphql/client';
	import type { PageData } from './$types';
	import { ContentContainer } from '$lib/components/layout';
	import type { Notification } from '$lib/graphql/queries/notifications';
	import {
		MARK_NOTIFICATION_AS_READ,
		MARK_ALL_NOTIFICATIONS_AS_READ,
		DELETE_NOTIFICATION,
		type MarkNotificationAsReadResult,
		type MarkAllNotificationsAsReadResult,
		type DeleteNotificationResult
	} from '$lib/graphql/mutations/notifications';
	import { unreadCounts } from '$lib/stores/unreadCounts.svelte';

	let { data }: { data: PageData } = $props();

	let notificationsOverride = $state<Notification[] | null>(null);
	let notifications = $derived(notificationsOverride ?? (data.notifications as Notification[]));
	let unreadOnly = $derived(data.unreadOnly);

	// Tab state - use $derived to track initial value
	let activeTabOverride = $state<'all' | 'unread' | null>(null);
	let activeTab = $derived(activeTabOverride ?? (unreadOnly ? 'unread' : 'all'));

	function formatRelativeTime(dateStr: string): string {
		const date = new Date(dateStr);
		const now = new Date();
		const diffMs = now.getTime() - date.getTime();
		const diffSecs = Math.floor(diffMs / 1000);
		const diffMins = Math.floor(diffSecs / 60);
		const diffHours = Math.floor(diffMins / 60);
		const diffDays = Math.floor(diffHours / 24);

		if (diffSecs < 60) return 'Just now';
		if (diffMins < 60) return `${diffMins}m ago`;
		if (diffHours < 24) return `${diffHours}h ago`;
		if (diffDays < 7) return `${diffDays}d ago`;
		return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
	}

	function getStatusColor(status: string): string {
		switch (status) {
			case 'PENDING':
				return 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400';
			case 'SENT':
				return 'bg-accent-100 text-accent-800 dark:bg-accent-900/30 dark:text-accent-400';
			case 'READ':
				return 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400';
			case 'FAILED':
				return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400';
			default:
				return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300';
		}
	}

	async function handleMarkAsRead(notification: Notification) {
		if (notification.isRead) return;

		try {
			await client.mutate<MarkNotificationAsReadResult>({
				mutation: MARK_NOTIFICATION_AS_READ,
				variables: { id: notification.id }
			});

			// Optimistic update
			notificationsOverride = notifications.map((n) =>
				n.id === notification.id ? { ...n, isRead: true, readAt: new Date().toISOString() } : n
			);
			unreadCounts.decrementNotifications();

			// Navigate to action URL if present
			if (notification.actionUrl) {
				goto(notification.actionUrl);
			}
		} catch (err) {
			console.error('Failed to mark notification as read:', err);
		}
	}

	async function handleMarkAllAsRead() {
		try {
			const result = await client.mutate<MarkAllNotificationsAsReadResult>({
				mutation: MARK_ALL_NOTIFICATIONS_AS_READ
			});

			const count = result.data?.markAllNotificationsAsRead ?? 0;

			// Optimistic update
			notificationsOverride = notifications.map((n) => ({
				...n,
				isRead: true,
				readAt: n.readAt ?? new Date().toISOString()
			}));

			// Update unread count
			unreadCounts.clearNotifications();
		} catch (err) {
			console.error('Failed to mark all notifications as read:', err);
		}
	}

	async function handleDelete(notification: Notification) {
		try {
			await client.mutate<DeleteNotificationResult>({
				mutation: DELETE_NOTIFICATION,
				variables: { id: notification.id }
			});

			// Optimistic update
			notificationsOverride = notifications.filter((n) => n.id !== notification.id);

			// Update unread count if was unread
			if (!notification.isRead) {
				unreadCounts.decrementNotifications();
			}
		} catch (err) {
			console.error('Failed to delete notification:', err);
		}
	}

	function switchTab(tab: 'all' | 'unread') {
		activeTabOverride = tab;
		notificationsOverride = null;
		goto(`/notifications${tab === 'unread' ? '?unread=true' : ''}`);
	}
</script>

<svelte:head>
	<title>Notifications - Nexus</title>
</svelte:head>

<div class="py-8">
	<ContentContainer>
		<!-- Header -->
		<div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
			<div>
				<h1 class="text-2xl font-bold text-accent6-600 md:text-3xl dark:text-accent6-400">
					Notifications
				</h1>
				<p class="mt-1 text-theme-secondary">Stay updated with your latest activity</p>
			</div>
			{#if notifications.some((n) => !n.isRead)}
				<button type="button" class="btn-secondary" onclick={handleMarkAllAsRead}>
					Mark all as read
				</button>
			{/if}
		</div>

		<!-- Tabs -->
		<div class="mb-6 flex gap-2 border-b border-theme">
			<button
				type="button"
				class="px-4 py-2 font-medium transition-colors {activeTab === 'all'
					? 'border-b-2 border-accent-500 text-accent-600 dark:text-accent-400'
					: 'text-theme-secondary hover:text-theme'}"
				onclick={() => switchTab('all')}
			>
				All
			</button>
			<button
				type="button"
				class="flex items-center gap-2 px-4 py-2 font-medium transition-colors {activeTab ===
				'unread'
					? 'border-b-2 border-accent-500 text-accent-600 dark:text-accent-400'
					: 'text-theme-secondary hover:text-theme'}"
				onclick={() => switchTab('unread')}
			>
				Unread
				{#if unreadCounts.notificationCount > 0}
					<span class="rounded-full bg-accent-500 px-2 py-0.5 text-xs font-semibold text-white">
						{unreadCounts.formattedNotificationCount}
					</span>
				{/if}
			</button>
		</div>

		<!-- Notifications List -->
		{#if notifications.length > 0}
			<div class="space-y-3">
				{#each notifications as notification (notification.id)}
					<div
						class="group hover:bg-theme-hover relative rounded-lg border border-theme bg-theme-card p-4 transition-colors {!notification.isRead
							? 'border-l-4 border-l-accent-500'
							: ''}"
					>
						<button
							type="button"
							class="w-full text-left"
							onclick={() => handleMarkAsRead(notification)}
						>
							<div class="flex items-start justify-between gap-4">
								<div class="min-w-0 flex-1">
									<!-- Subject -->
									<h3
										class="font-semibold text-theme {!notification.isRead
											? ''
											: 'text-theme-secondary'}"
									>
										{notification.subject}
									</h3>

									<!-- Body -->
									<p class="mt-1 line-clamp-2 text-sm text-theme-secondary">
										{notification.body}
									</p>

									<!-- Meta -->
									<div class="mt-2 flex flex-wrap items-center gap-3 text-xs text-theme-muted">
										<span>{formatRelativeTime(notification.createdAt)}</span>
										{#if notification.event}
											<span class="rounded bg-gray-100 px-2 py-0.5 dark:bg-gray-700">
												{notification.event.eventType.replace(/_/g, ' ')}
											</span>
										{/if}
									</div>
								</div>

								<!-- Unread indicator -->
								{#if !notification.isRead}
									<span class="h-2.5 w-2.5 shrink-0 rounded-full bg-accent-500"></span>
								{/if}
							</div>
						</button>

						<!-- Delete button (visible on hover) -->
						<button
							type="button"
							class="absolute top-2 right-2 rounded p-1 text-theme-muted opacity-0 transition-opacity group-hover:opacity-100 hover:bg-red-100 hover:text-red-600 dark:hover:bg-red-900/30 dark:hover:text-red-400"
							onclick={(e) => {
								e.stopPropagation();
								handleDelete(notification);
							}}
							aria-label="Delete notification"
						>
							<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
								<path
									stroke-linecap="round"
									stroke-linejoin="round"
									stroke-width="2"
									d="M6 18L18 6M6 6l12 12"
								/>
							</svg>
						</button>
					</div>
				{/each}
			</div>
		{:else}
			<!-- Empty state -->
			<div class="rounded-lg border border-dashed border-theme py-12 text-center">
				<svg
					class="mx-auto h-12 w-12 text-theme-muted"
					fill="none"
					stroke="currentColor"
					viewBox="0 0 24 24"
				>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="1.5"
						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>
				<h3 class="mt-4 text-lg font-medium text-theme">
					{activeTab === 'unread' ? 'No unread notifications' : 'No notifications yet'}
				</h3>
				<p class="mt-2 text-theme-secondary">
					{activeTab === 'unread'
						? "You're all caught up!"
						: "When you receive notifications, they'll appear here."}
				</p>
			</div>
		{/if}
	</ContentContainer>
</div>
