<script lang="ts">
	import { Button } from '$lib/components/ui/button';
	import WalkInCreateModal from '$lib/components/admin/WalkInCreateModal.svelte';
	import { authStore } from '$lib/stores/auth.svelte';
	import { CalendarDate } from '@internationalized/date';
	import { SvelteDate } from 'svelte/reactivity';
	import { onMount } from 'svelte';

	import type { AvailableHoursDay } from '$lib/types/booking';

	let showCreateModal = $state(false);
	let slotInfo = $state<{
		isAvailableNow: boolean;
		waitMinutes?: number;
		durationMinutes: number;
		startTime?: string;
		slotEndMinutes?: number; // Store for live countdown
	} | null>(null);
	let loading = $state(true);
	let noSlotsToday = $state(false);
	let currentTime = $state(new Date());

	onMount(() => {
		calculateSlotAvailability();

		// Update current time every minute for live countdown
		const interval = setInterval(() => {
			currentTime = new Date();
		}, 60000); // Update every minute

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

	/**
	 * Converts "HH:MM" or "HH:MM:SS" time string to minutes since midnight
	 */
	function timeToMinutes(time: string): number {
		const parts = time.split(':').map(Number);
		return parts[0] * 60 + parts[1];
	}

	/**
	 * Converts minutes to hours and minutes for display
	 */
	function formatDuration(minutes: number): string {
		const hours = Math.floor(minutes / 60);
		const mins = minutes % 60;

		if (hours > 0 && mins > 0) {
			return `${hours} hour${hours !== 1 ? 's' : ''}, ${mins} minute${mins !== 1 ? 's' : ''}`;
		} else if (hours > 0) {
			return `${hours} hour${hours !== 1 ? 's' : ''}`;
		} else {
			return `${mins} minute${mins !== 1 ? 's' : ''}`;
		}
	}

	/**
	 * Calculate live remaining time based on current time
	 */
	function getLiveRemainingMinutes(): number | null {
		if (!slotInfo?.isAvailableNow || !slotInfo.slotEndMinutes) return null;

		const now = currentTime.getHours() * 60 + currentTime.getMinutes();
		const remaining = slotInfo.slotEndMinutes - now;
		return Math.max(0, remaining);
	}

	/**
	 * Calculate live wait time based on current time
	 */
	function getLiveWaitMinutes(): number | null {
		if (slotInfo?.isAvailableNow || !slotInfo?.startTime) return null;

		const now = currentTime.getHours() * 60 + currentTime.getMinutes();
		const slotStartMinutes = timeToMinutes(slotInfo.startTime);
		const wait = slotStartMinutes - now;
		return Math.max(0, wait);
	}

	async function calculateSlotAvailability() {
		loading = true;
		noSlotsToday = false;

		try {
			const now = new SvelteDate();
			const today = new CalendarDate(now.getFullYear(), now.getMonth() + 1, now.getDate());

			// Fetch today's available hours
			const response = await fetch(`/api/scheduling/available-hours?start=${today}&end=${today}`, {
				headers: { Authorization: `Bearer ${authStore.currentToken}` }
			});

			if (!response.ok) {
				noSlotsToday = true;
				return;
			}

			const data: AvailableHoursDay[] = await response.json();
			const todayData = data[0];

			if (!todayData || !todayData.isOpen || !todayData.slots || todayData.slots.length === 0) {
				noSlotsToday = true;
				return;
			}

			// Current time in minutes since midnight
			const currentMinutes = now.getHours() * 60 + now.getMinutes();

			// Check if we're currently in an available slot
			for (const slot of todayData.slots) {
				const slotStartMinutes = timeToMinutes(slot.startTime);
				const slotEndMinutes = timeToMinutes(slot.endTime);

				// Are we currently within this slot?
				if (currentMinutes >= slotStartMinutes && currentMinutes < slotEndMinutes) {
					const remainingMinutes = slotEndMinutes - currentMinutes;
					slotInfo = {
						isAvailableNow: true,
						durationMinutes: remainingMinutes,
						slotEndMinutes: slotEndMinutes // Store for live countdown
					};
					return;
				}

				// Is this a future slot?
				if (slotStartMinutes > currentMinutes) {
					const waitMinutes = slotStartMinutes - currentMinutes;
					const durationMinutes = slotEndMinutes - slotStartMinutes;
					slotInfo = {
						isAvailableNow: false,
						waitMinutes,
						durationMinutes,
						startTime: slot.startTime
					};
					return;
				}
			}

			// No current or future slots available
			noSlotsToday = true;
		} catch (err) {
			console.error('Failed to calculate slot availability', err);
			noSlotsToday = true;
		} finally {
			loading = false;
		}
	}

	function formatTime(time: string): string {
		const [hours, minutes] = time.split(':').map(Number);
		const period = hours >= 12 ? 'PM' : 'AM';
		const displayHours = hours % 12 || 12;
		return `${displayHours}:${minutes.toString().padStart(2, '0')} ${period}`;
	}
</script>

<div class="rounded-lg border border-gray-200 bg-white p-4">
	<h3 class="mb-2 text-sm font-semibold tracking-wide text-gray-600 uppercase">Walk-In Booking</h3>

	{#if loading}
		<div class="mb-4 h-12 animate-pulse rounded bg-gray-100"></div>
	{:else if noSlotsToday}
		<p class="mb-4 text-sm text-gray-500">No slots available for walk-in today</p>
	{:else if slotInfo?.isAvailableNow}
		{@const liveRemaining = getLiveRemainingMinutes()}
		{#if liveRemaining !== null && liveRemaining > 0}
			<p class="mb-4 text-sm text-gray-500">
				Available now for <span class="font-semibold text-gray-700"
					>{formatDuration(liveRemaining)}</span
				>
			</p>
		{:else}
			<p class="mb-4 text-sm text-gray-500">No slots available for walk-in today</p>
		{/if}
	{:else if slotInfo && !slotInfo.isAvailableNow}
		{@const liveWait = getLiveWaitMinutes()}
		{#if liveWait !== null && liveWait > 0}
			<p class="mb-4 text-sm text-gray-500">
				Next slot available in <span class="font-semibold text-gray-700"
					>{formatDuration(liveWait)}</span
				>
				at {formatTime(slotInfo.startTime!)}, for
				<span class="font-semibold text-gray-700">{formatDuration(slotInfo.durationMinutes)}</span>
			</p>
		{:else}
			<p class="mb-4 text-sm text-gray-500">
				Available now for <span class="font-semibold text-gray-700"
					>{formatDuration(slotInfo.durationMinutes)}</span
				>
			</p>
		{/if}
	{/if}

	<div class="flex items-center gap-3">
		<Button
			onclick={() => (showCreateModal = true)}
			disabled={noSlotsToday || (slotInfo?.isAvailableNow && (getLiveRemainingMinutes() ?? 0) <= 0)}
		>
			Start Walk-In Session
		</Button>
	</div>
</div>

{#if showCreateModal}
	<WalkInCreateModal
		bind:open={showCreateModal}
		maxSlotDuration={slotInfo?.durationMinutes ?? 0}
		availableStartTime={slotInfo?.isAvailableNow ? undefined : slotInfo?.startTime}
	/>
{/if}
