<script lang="ts">
	import { Bell, Check, CheckCheck, X, Calendar, CreditCard, Users, Megaphone, Settings } from 'lucide-svelte';
	import { onMount } from 'svelte';
	import { goto } from '$app/navigation';
	import { LoadingSpinner } from '$lib/components/ui';

	interface Notification {
		id: string;
		type: 'welcome' | 'event' | 'payment' | 'membership' | 'system' | 'announcement';
		title: string;
		message: string;
		link: string | null;
		read_at: string | null;
		created_at: string;
	}

	let isOpen = $state(false);
	let notifications = $state<Notification[]>([]);
	let loading = $state(true);
	let error = $state<string | null>(null);

	const unreadCount = $derived(notifications.filter(n => !n.read_at).length);

	function toggleDropdown() {
		isOpen = !isOpen;
		if (isOpen && notifications.length === 0) {
			loadNotifications();
		}
	}

	function closeDropdown() {
		isOpen = false;
	}

	function handleClickOutside(event: MouseEvent) {
		const target = event.target as HTMLElement;
		if (!target.closest('.notification-center')) {
			closeDropdown();
		}
	}

	async function loadNotifications() {
		loading = true;
		error = null;

		try {
			const response = await fetch('/api/notifications');
			if (!response.ok) {
				throw new Error('Failed to load notifications');
			}
			const data = await response.json();
			notifications = data.notifications || [];
		} catch (e) {
			error = e instanceof Error ? e.message : 'Failed to load notifications';
		} finally {
			loading = false;
		}
	}

	async function markAsRead(id: string) {
		try {
			const response = await fetch(`/api/notifications/${id}/read`, {
				method: 'POST'
			});
			if (response.ok) {
				notifications = notifications.map(n =>
					n.id === id ? { ...n, read_at: new Date().toISOString() } : n
				);
			}
		} catch (e) {
			console.error('Failed to mark notification as read:', e);
		}
	}

	async function markAllAsRead() {
		try {
			const response = await fetch('/api/notifications/read-all', {
				method: 'POST'
			});
			if (response.ok) {
				const now = new Date().toISOString();
				notifications = notifications.map(n => ({ ...n, read_at: n.read_at || now }));
			}
		} catch (e) {
			console.error('Failed to mark all notifications as read:', e);
		}
	}

	async function handleNotificationClick(notification: Notification) {
		if (!notification.read_at) {
			markAsRead(notification.id);
		}
		closeDropdown();
		// Always go to notifications page with the notification ID to expand it
		await goto(`/notifications?id=${notification.id}`);
	}

	function getTypeIcon(type: Notification['type']) {
		switch (type) {
			case 'welcome': return Users;
			case 'event': return Calendar;
			case 'payment': return CreditCard;
			case 'membership': return Users;
			case 'system': return Settings;
			case 'announcement': return Megaphone;
			default: return Bell;
		}
	}

	function getTypeColor(type: Notification['type']) {
		switch (type) {
			case 'welcome': return 'text-green-600 bg-green-100';
			case 'event': return 'text-blue-600 bg-blue-100';
			case 'payment': return 'text-amber-600 bg-amber-100';
			case 'membership': return 'text-purple-600 bg-purple-100';
			case 'system': return 'text-slate-600 bg-slate-100';
			case 'announcement': return 'text-monaco-600 bg-monaco-100';
			default: return 'text-slate-600 bg-slate-100';
		}
	}

	function formatTime(dateString: string) {
		const date = new Date(dateString);
		const now = new Date();
		const diffMs = now.getTime() - date.getTime();
		const diffMins = Math.floor(diffMs / 60000);
		const diffHours = Math.floor(diffMs / 3600000);
		const diffDays = Math.floor(diffMs / 86400000);

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

	onMount(() => {
		loadNotifications();
	});
</script>

<svelte:window onclick={handleClickOutside} />

<div class="notification-center relative">
	<!-- Bell Button -->
	<button
		onclick={toggleDropdown}
		class="relative rounded-lg p-2 text-slate-500 hover:bg-slate-100 active:bg-slate-200 transition-colors min-h-[44px] min-w-[44px]"
		aria-label="Notifications"
		aria-expanded={isOpen}
		aria-haspopup="true"
	>
		<Bell class="h-5 w-5" />
		{#if unreadCount > 0}
			<span
				class="absolute right-1 top-1 flex h-4 w-4 items-center justify-center rounded-full bg-monaco-600 text-[10px] font-medium text-white"
			>
				{unreadCount > 9 ? '9+' : unreadCount}
			</span>
		{/if}
	</button>

	<!-- Dropdown -->
	{#if isOpen}
		<div
			class="absolute right-0 top-full mt-2 w-80 sm:w-96 origin-top-right rounded-xl border border-slate-200 bg-white shadow-lg ring-1 ring-black/5 z-50"
			role="menu"
		>
			<!-- Header -->
			<div class="flex items-center justify-between border-b border-slate-100 px-4 py-3">
				<h3 class="font-semibold text-slate-900">Notifications</h3>
				{#if unreadCount > 0}
					<button
						onclick={markAllAsRead}
						class="flex items-center gap-1 text-xs text-monaco-600 hover:text-monaco-700 transition-colors"
					>
						<CheckCheck class="h-3.5 w-3.5" />
						Mark all read
					</button>
				{/if}
			</div>

			<!-- Notifications List -->
			<div class="max-h-96 overflow-y-auto">
				{#if loading}
					<div class="flex items-center justify-center py-8">
						<LoadingSpinner size="lg" class="text-monaco-600" />
					</div>
				{:else if error}
					<div class="px-4 py-8 text-center">
						<p class="text-sm text-red-600">{error}</p>
						<button
							onclick={loadNotifications}
							class="mt-2 text-sm text-monaco-600 hover:text-monaco-700"
						>
							Try again
						</button>
					</div>
				{:else if notifications.length === 0}
					<div class="px-4 py-8 text-center">
						<Bell class="mx-auto h-8 w-8 text-slate-300" />
						<p class="mt-2 text-sm text-slate-500">No notifications yet</p>
					</div>
				{:else}
					{#each notifications as notification}
						{@const Icon = getTypeIcon(notification.type)}
						<button
							onclick={() => handleNotificationClick(notification)}
							class="flex w-full items-start gap-3 px-4 py-3 text-left hover:bg-slate-50 transition-colors {notification.read_at ? 'opacity-60' : ''}"
							role="menuitem"
						>
							<div class="flex-shrink-0 rounded-full p-2 {getTypeColor(notification.type)}">
								<Icon class="h-4 w-4" />
							</div>
							<div class="min-w-0 flex-1">
								<div class="flex items-start justify-between gap-2">
									<p class="text-sm font-medium text-slate-900 {notification.read_at ? '' : 'font-semibold'}">
										{notification.title}
									</p>
									{#if !notification.read_at}
										<span class="flex-shrink-0 h-2 w-2 rounded-full bg-monaco-600"></span>
									{/if}
								</div>
								<p class="mt-0.5 text-xs text-slate-600 line-clamp-2">{notification.message}</p>
								<p class="mt-1 text-xs text-slate-400">{formatTime(notification.created_at)}</p>
							</div>
						</button>
					{/each}
				{/if}
			</div>

			<!-- Footer -->
			{#if notifications.length > 0}
				<div class="border-t border-slate-100 px-4 py-2">
					<a
						href="/notifications"
						onclick={closeDropdown}
						class="block text-center text-sm text-monaco-600 hover:text-monaco-700 transition-colors py-1"
					>
						View all notifications
					</a>
				</div>
			{/if}
		</div>
	{/if}
</div>
