<script lang="ts">
	/**
	 * SystemAnnouncements — viser aktive systemvarsler som banner/toast.
	 *
	 * Filtrerer nodeStore for noder med node_kind='system_announcement',
	 * skjuler utløpte varsler (expires_at), og viser nedtelling for
	 * planlagte hendelser (scheduled_at).
	 *
	 * Varslingstyper:
	 * - info: blå banner (generell melding)
	 * - warning: gul banner (planlagt vedlikehold med nedtelling)
	 * - critical: rød banner (umiddelbar handling kreves)
	 *
	 * Ref: docs/concepts/adminpanelet.md § "Systemvarsler og vedlikeholdsmodus"
	 * Oppgave 15.1
	 */

	import { nodeStore, connectionState } from '$lib/realtime';
	import type { Node } from '$lib/realtime';

	const connected = $derived(connectionState.current === 'connected');

	// Tick every second for countdown updates
	let now = $state(Date.now());
	$effect(() => {
		const interval = setInterval(() => {
			now = Date.now();
		}, 1000);
		return () => clearInterval(interval);
	});

	interface AnnouncementMeta {
		announcement_type: 'info' | 'warning' | 'critical';
		scheduled_at?: string | null;
		expires_at?: string | null;
		blocks_new_sessions?: boolean;
	}

	function parseMeta(node: Node): AnnouncementMeta | null {
		try {
			const meta = JSON.parse(node.metadata ?? '{}');
			if (!meta.announcement_type) return null;
			return meta as AnnouncementMeta;
		} catch {
			return null;
		}
	}

	/** Active (non-expired) system announcements, sorted by type priority. */
	const announcements = $derived.by(() => {
		if (!connected) return [];

		const typePriority: Record<string, number> = { critical: 0, warning: 1, info: 2 };
		const result: Array<{ node: Node; meta: AnnouncementMeta }> = [];

		for (const node of nodeStore.byKind('system_announcement')) {
			const meta = parseMeta(node);
			if (!meta) continue;

			// Skip expired announcements
			if (meta.expires_at) {
				const expiresAt = new Date(meta.expires_at).getTime();
				if (expiresAt <= now) continue;
			}

			result.push({ node, meta });
		}

		// Sort: critical first, then warning, then info
		result.sort((a, b) => {
			const pa = typePriority[a.meta.announcement_type] ?? 9;
			const pb = typePriority[b.meta.announcement_type] ?? 9;
			return pa - pb;
		});

		return result;
	});

	/** Format countdown string from now to a target date. */
	function countdown(targetIso: string): string {
		const target = new Date(targetIso).getTime();
		const diff = target - now;

		if (diff <= 0) return 'nå';

		const seconds = Math.floor(diff / 1000);
		const minutes = Math.floor(seconds / 60);
		const hours = Math.floor(minutes / 60);

		if (hours > 0) {
			const remainMinutes = minutes % 60;
			return `${hours}t ${remainMinutes}m`;
		}
		if (minutes > 0) {
			const remainSeconds = seconds % 60;
			return `${minutes}m ${remainSeconds}s`;
		}
		return `${seconds}s`;
	}

	// Dismissed announcements (per session, not persisted)
	let dismissed = $state<Set<string>>(new Set());

	function dismiss(nodeId: string) {
		dismissed = new Set([...dismissed, nodeId]);
	}
</script>

{#if announcements.length > 0}
	<div class="fixed top-0 left-0 right-0 z-50 flex flex-col gap-0">
		{#each announcements as { node, meta } (node.id)}
			{#if !dismissed.has(node.id)}
				{@const isCritical = meta.announcement_type === 'critical'}
				{@const isWarning = meta.announcement_type === 'warning'}
				<div
					class="flex items-center justify-between gap-3 px-4 py-2.5 text-sm shadow-sm {
						isCritical
							? 'bg-red-600 text-white'
							: isWarning
								? 'bg-amber-500 text-amber-950'
								: 'bg-blue-500 text-white'
					}"
					role="alert"
				>
					<div class="mx-auto flex max-w-4xl flex-1 items-center gap-3">
						<!-- Icon -->
						<span class="shrink-0 text-base" aria-hidden="true">
							{#if isCritical}⚠{:else if isWarning}🔧{:else}ℹ{/if}
						</span>

						<!-- Message -->
						<div class="flex-1">
							<span class="font-semibold">{node.title}</span>
							{#if node.content}
								<span class="ml-1 opacity-90">— {node.content}</span>
							{/if}
						</div>

						<!-- Countdown (for scheduled events) -->
						{#if meta.scheduled_at}
							{@const remaining = countdown(meta.scheduled_at)}
							<span class="shrink-0 rounded-full px-2.5 py-0.5 text-xs font-bold {
								isCritical
									? 'bg-red-800 text-red-100'
									: isWarning
										? 'bg-amber-700 text-amber-100'
										: 'bg-blue-700 text-blue-100'
							}">
								om {remaining}
							</span>
						{/if}

						<!-- Dismiss button (not for critical) -->
						{#if !isCritical}
							<button
								onclick={() => dismiss(node.id)}
								class="shrink-0 rounded p-1 opacity-70 hover:opacity-100 {
									isWarning ? 'hover:bg-amber-600' : 'hover:bg-blue-600'
								}"
								aria-label="Lukk varsel"
							>
								<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="M6 18L18 6M6 6l12 12" />
								</svg>
							</button>
						{/if}
					</div>
				</div>
			{/if}
		{/each}
	</div>
{/if}
