<script lang="ts">
	import { onMount, untrack } from 'svelte';
	import { quickLinks } from '$lib/quick-links.svelte';
	import { invalidateAll } from '$app/navigation';
	import StationAlertCard from '$lib/components/ui/station-board/StationAlertCard.svelte';

	import { formatUkDateTime, formatUkTime } from '$lib/utils/time';
	import StaffServicesGrid from '$lib/components/ui/station-board/StaffServicesGrid.svelte';

	let { data } = $props();
	let now = $state(new Date());
	let dataAgeInSeconds = $derived(
		Math.floor((now.getTime() - new Date(data.boardData.producedAt).getTime()) / 1000)
	);
	let live = $derived(dataAgeInSeconds < 45);

	// Handle auto-refreshing & Wake-lock
	$effect(() => {
		let intervalId: number | undefined;
		let wakeLock: WakeLockSentinel | null = null;

		const requestWakeLock = async () => {
			if ('wakeLock' in navigator && !wakeLock) {
				try {
					wakeLock = await navigator.wakeLock.request('screen');
					console.log('Wake lock obtained');
				} catch (error) {
					console.warn('Wake lock request rejected: ', error);
				}
			}
		};

		const releaseWakeLock = async () => {
			if (wakeLock) {
				try {
					await wakeLock.release();
					console.log('Wake lock released');
				} catch (error) {
					console.error('Wake lock release failed: ', error);
				}
				wakeLock = null;
			}
		};

		const startPolling = async () => {
			await requestWakeLock();
			if (intervalId) return;
			intervalId = window.setInterval(async () => {
				try {
					console.log('Invalidating data');
					await invalidateAll();
				} catch (error) {
					console.error('Background data fetch failed: ', error);
				}
			}, 20000);
			console.log('Polling started');
		};

		const stopPolling = async () => {
			if (intervalId) {
				window.clearInterval(intervalId);
				intervalId = undefined;
				console.log('Polling ended');
			}
			await releaseWakeLock();
		};

		const handleVisibilityChange = async () => {
			if (document.hidden) {
				stopPolling();
			} else {
				startPolling();
				await invalidateAll();
			}
		};

		if (!document.hidden) {
			startPolling();
		}

		document.addEventListener('visibilitychange', handleVisibilityChange);

		return () => {
			stopPolling();
			document.removeEventListener('visibilitychange', handleVisibilityChange);
		};
	});

	onMount(() => {
		const interval = setInterval(() => {
			now = new Date();
		}, 1000);

		return () => clearInterval(interval);
	});

	const currentBoardId = $derived(
		data.BoardLocation ? (data.BoardLocation.c ?? data.BoardLocation.t) : null
	);

	// Update 'QuickLinks' when currentBoardId changes
	$effect(() => {
		if (currentBoardId) {
			// Keep the execution and logs inside untrack to isolate dependencies completely
			untrack(() => {
				quickLinks.recordVisit(currentBoardId);
				console.log(`QuickLink visit recorded: ${JSON.stringify(data.BoardLocation)}`);
			});
		}
	});
</script>

<section class="board-wrapper">
	<div class="time-data">
		<div class="loadedlive">
			<div class="liveflash {live ? 'isLive' : 'notLive'}"></div>
			<span class="time-loaded">Updated: {formatUkDateTime(data.boardData.producedAt, true)}</span>
		</div>
		<span class="time-now">{formatUkTime(now, true)}</span>
	</div>
	{#if data.boardData.data.m?.length}
		<StationAlertCard messages={data.boardData.data.m} />
	{/if}
	{#if data.boardData.data.s?.length}
		<div class="service-list-wrapper">
			<StaffServicesGrid services={data.boardData.data.s} />
		</div>
	{:else}
		<div class="no-service">No services at this location in the next three hours</div>
	{/if}
</section>

<style>
	.board-wrapper {
		display: flex;
		height: calc(100dvh - var(--nav-height) - var(--header-height));
		flex-direction: column;
		align-items: center;
		width: 100%;
		margin: 0 auto;
		padding: 0;
		overflow: hidden;
		gap: 0;
	}

	.no-service {
		display: block;
		margin: auto;
		text-align: center;
		font-weight: 600;
		letter-spacing: 0.15ch;
		font-size: 1.4rem;
		max-width: 75%;
		font-family: 'URW Gothic', sans-serif;
	}

	.time-data {
		display: flex;
		justify-content: space-between;
		align-items: center;
		width: 90%;
		max-width: 700px;
		margin: 10px auto;
		font-family: 'URW Gothic', sans-serif;
	}

	.loadedlive {
		display: inline-flex;
		justify-content: center;
		align-items: center;
		gap: 1rem;
	}

	.liveflash {
		width: 12px;
		height: 12px;
		border-radius: 50%;
		transition: all 0.3s ease;
	}

	div.notLive {
		background-color: #ef4444;
		animation:
			led-blink 1s steps(1, start) infinite,
			led-halo-expand 1s steps(1, start) infinite;
	}

	div.isLive {
		background-color: #10b981;
		animation: led-pulse 2.5s infinite ease-in-out;
	}

	@keyframes led-blink {
		0%,
		100% {
			opacity: 1;
		}
		50% {
			opacity: 0.2;
			filter: saturate(0.2);
		}
	}
	@keyframes led-pulse {
		0%,
		100% {
			opacity: 1;
			filter: saturate(1);
			box-shadow: 0 0 6px 1px rgba(16, 185, 129, 0.4);
		}
		50% {
			opacity: 0.2;
			filter: saturate(0.2);
			box-shadow: 0 0 2px 0px rgba(16, 185, 129, 0.1);
		}
	}

	.time-loaded,
	.time-now {
		font-variant-numeric: tabular-nums;
	}

	.time-loaded {
		font-size: 0.9rem;
	}

	.time-now {
		font-weight: 600;
		font-size: 1rem;
	}

	.service-list-wrapper {
		flex: 1;
		overflow-y: auto;
		height: calc(100dvh - 60px);
		width: 97%;
		max-width: 700px;
		margin-bottom: 5px;
	}
</style>
