<script lang="ts">
	import { authStore } from '$lib/stores/auth.svelte';
	import { toast } from 'svelte-sonner';
	import { browser } from '$app/environment';

	// shadcn-svelte components
	import { Button } from '$lib/components/ui/button';
	import * as Card from '$lib/components/ui/card';
	import { Checkbox } from '$lib/components/ui/checkbox';
	import * as Modal from '$lib/components/ui/dialog';
	import * as AlertDialog from '$lib/components/ui/alert-dialog';
	import { Skeleton } from '$lib/components/ui/skeleton';

	const TIME15 = ['00', '15', '30', '45'];

	// =============== Types ===============
	type WorkingHourRow = {
		weekday: number;
		start_time: string;
		end_time: string;
		is_open: boolean;
	};

	// =============== State ===============
	let defaultHours = $state<WorkingHourRow[]>([]);
	let defaultHoursIsLoading = $state(true);
	let defaultHoursDraft = $state<WorkingHourRow[]>([]);
	let showDefaultHoursModal = $state(false);
	let showSaveDefaultHoursAlert = $state(false);
	let savingHours = $state(false);

	const dayNames = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];

	// =============== Helper Functions ===============
	/** Format time from HH:MM:SS to 12-hour format, with "Noon" for 12:00 PM */
	function formatTime(time: string): string {
		const [hours, minutes] = time.split(':').map(Number);

		// Special case for 12:00
		if (hours === 12 && minutes === 0) {
			return 'Noon';
		} else if (hours === 0 && minutes === 0) {
			return 'Midnight';
		}

		const period = hours >= 12 ? 'PM' : 'AM';
		const displayHours = hours % 12 || 12;
		return `${displayHours}:${minutes.toString().padStart(2, '0')} ${period}`;
	}

	/** Convert formatted time back to HH:MM for input fields */
	function timeToInputValue(time: string): string {
		// Handle special cases
		if (time === 'Noon') return '12:00';
		if (time === 'Midnight') return '00:00';

		// Parse 12-hour format
		const match = time.match(/^(\d{1,2}):(\d{2})\s*(AM|PM)$/i);
		if (!match) return time; // Return as-is if not in expected format

		let hours = parseInt(match[1]);
		const minutes = match[2];
		const period = match[3].toUpperCase();

		if (period === 'PM' && hours !== 12) hours += 12;
		if (period === 'AM' && hours === 12) hours = 0;

		return `${hours.toString().padStart(2, '0')}:${minutes}`;
	}

	function weekdayLabel(i: number): string {
		return dayNames[i];
	}

	/** Calculate hours between start and end time */
	function calculateHours(startTime: string, endTime: string): string {
		// Convert formatted times to 24-hour format for calculation
		const start = timeToInputValue(startTime);
		const end = timeToInputValue(endTime);

		const [startHours, startMinutes] = start.split(':').map(Number);
		const [endHours, endMinutes] = end.split(':').map(Number);

		const startTotalMinutes = startHours * 60 + startMinutes;
		const endTotalMinutes = endHours * 60 + endMinutes;

		const diffMinutes = endTotalMinutes - startTotalMinutes;
		const hours = Math.floor(diffMinutes / 60);
		const minutes = diffMinutes % 60;

		if (minutes === 0) {
			return `${hours}`;
		}
		return `${hours}.${minutes === 30 ? '5' : Math.round((minutes / 60) * 10)}`;
	}

	// =============== API Functions ===============
	async function fetchDefaultHours() {
		if (!browser) return;

		defaultHoursIsLoading = true;
		let error = null;

		try {
			const response = await fetch('/api/scheduling/default-hours', {
				method: 'GET',
				headers: {
					'Content-Type': 'application/json',
					Authorization: `Bearer ${authStore.currentToken}`
				}
			});

			if (response.ok) {
				const data = await response.json();
				defaultHours = data.map((hour: any) => ({
					weekday: hour.weekday,
					start_time: formatTime(hour.startTime),
					end_time: formatTime(hour.endTime),
					is_open: hour.isOpen
				}));
			} else {
				const text = await response.text();
				error = 'Failed to load working hours: ' + text;
				console.error('Error fetching default hours:', text);
			}
		} catch (err) {
			error = 'Network error: ' + (err instanceof Error ? err.message : 'Unknown error');
			console.error('Error fetching default hours:', err);
		} finally {
			if (error) toast.error(error);
			defaultHoursIsLoading = false;
		}
	}

	/** Opens the modal and creates a deep copy of current hours for editing. */
	function prepareDefaultHoursEdit() {
		// Deep copy the current default hours into the draft state
		defaultHoursDraft = JSON.parse(JSON.stringify(defaultHours));
		// Convert display format back to input format
		defaultHoursDraft = defaultHoursDraft.map((row) => ({
			...row,
			start_time: timeToInputValue(row.start_time),
			end_time: timeToInputValue(row.end_time)
		}));
		showDefaultHoursModal = true;
	}

	/** Saves the default hours draft after confirmation. */
	async function confirmSaveDefaultHours() {
		savingHours = true;
		const loadingToast = toast.loading('Saving default hours...');

		try {
			// Map snake_case to camelCase for API
			const payload = defaultHoursDraft.map((hour) => ({
				weekday: hour.weekday,
				startTime: hour.start_time,
				endTime: hour.end_time,
				isOpen: hour.is_open
			}));

			const response = await fetch('/api/scheduling/default-hours', {
				method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					Authorization: `Bearer ${authStore.currentToken}`
				},
				body: JSON.stringify(payload)
			});

			if (response.ok) {
				// Update the main state from the draft state if successful
				defaultHours = JSON.parse(JSON.stringify(defaultHoursDraft));
				showDefaultHoursModal = false;
				showSaveDefaultHoursAlert = false;
				toast.success('Default hours saved successfully!', { id: loadingToast });
			} else if (response.status === 401 || response.status === 403) {
				toast.error('Unauthorized. Please log in again.', { id: loadingToast });
			} else {
				const text = await response.text();
				toast.error('Failed to save: ' + text, { id: loadingToast });
			}
		} catch (err) {
			console.error('save default hours', err);
			toast.error('Network error saving hours', { id: loadingToast });
		} finally {
			savingHours = false;
		}
	}

	// =============== Effects ===============
	$effect(() => {
		if (browser) {
			fetchDefaultHours();
		}
	});
</script>

<!-- Default Hours Card -->
<Card.Root>
	{#if !defaultHoursIsLoading}
		<Card.Content class="space-y-4">
			<div class="flex items-center justify-between">
				<div>
					<h3 class="text-lg font-semibold">Weekly Schedule</h3>
					<p class="text-sm text-gray-500">
						Your standard operating hours for each day of the week
					</p>
				</div>
				<Button onclick={prepareDefaultHoursEdit} disabled={savingHours}>
					<svg
						xmlns="http://www.w3.org/2000/svg"
						class="mr-2 h-4 w-4"
						viewBox="0 0 24 24"
						fill="none"
						stroke="currentColor"
						stroke-width="2"
					>
						<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
						<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
					</svg>
					Edit Schedule
				</Button>
			</div>
			<!-- Desktop Table -->
			<div class="hidden w-full overflow-x-auto sm:block">
				<table class="w-full table-auto border-collapse">
					<thead>
						<tr class="border-b text-left text-xs text-gray-500">
							<th class="px-4 py-3">Day</th>
							<th class="px-4 py-3 text-center">Status</th>
							<th class="px-4 py-3">Opening Time</th>
							<th class="px-4 py-3">Closing Time</th>
							<th class="px-4 py-3 text-right">Total Hours</th>
						</tr>
					</thead>
					<tbody class="divide-y divide-gray-200">
						{#each defaultHours as row (row.weekday)}
							<tr class="transition-colors hover:bg-gray-50">
								<td class="p-3">
									<div class="flex items-center gap-2">
										<span class="font-medium"
											>{weekdayLabel(row.weekday) === 'Mon'
												? 'Monday'
												: weekdayLabel(row.weekday) === 'Tue'
													? 'Tuesday'
													: weekdayLabel(row.weekday) === 'Wed'
														? 'Wednesday'
														: weekdayLabel(row.weekday) === 'Thu'
															? 'Thursday'
															: weekdayLabel(row.weekday) === 'Fri'
																? 'Friday'
																: weekdayLabel(row.weekday) === 'Sat'
																	? 'Saturday'
																	: 'Sunday'}</span
										>
									</div>
								</td>
								<td class="px-4 py-4 text-center">
									<span
										class="inline-flex items-center rounded-full px-3 py-1 text-xs font-medium {row.is_open
											? 'bg-emerald-100 text-emerald-800'
											: 'bg-gray-100 text-gray-800'}"
									>
										<span
											class="mr-1.5 h-1.5 w-1.5 rounded-full {row.is_open
												? 'bg-emerald-600'
												: 'bg-gray-600'}"
										></span>
										{row.is_open ? 'Open' : 'Closed'}
									</span>
								</td>
								<td class="px-4 py-4">
									{#if row.is_open}
										<div class="flex items-center gap-2">
											<svg
												xmlns="http://www.w3.org/2000/svg"
												class="h-4 w-4 text-gray-400"
												viewBox="0 0 24 24"
												fill="none"
												stroke="currentColor"
												stroke-width="2"
											>
												<circle cx="12" cy="12" r="10" />
												<polyline points="12 6 12 12 16 14" />
											</svg>
											<span class="font-medium text-gray-900">{row.start_time}</span>
										</div>
									{:else}
										<span class="text-gray-400">—</span>
									{/if}
								</td>
								<td class="px-4 py-4">
									{#if row.is_open}
										<div class="flex items-center gap-2">
											<svg
												xmlns="http://www.w3.org/2000/svg"
												class="h-4 w-4 text-gray-400"
												viewBox="0 0 24 24"
												fill="none"
												stroke="currentColor"
												stroke-width="2"
											>
												<circle cx="12" cy="12" r="10" />
												<polyline points="12 6 12 12 16 14" />
											</svg>
											<span class="font-medium text-gray-900">{row.end_time}</span>
										</div>
									{:else}
										<span class="text-gray-400">—</span>
									{/if}
								</td>
								<td class="px-4 py-4 text-right">
									{#if row.is_open}
										<span class="inline-flex items-center gap-1 text-sm font-medium text-gray-700">
											{calculateHours(row.start_time, row.end_time)}
											<span class="text-xs text-gray-500">hrs</span>
										</span>
									{:else}
										<span class="text-gray-400">—</span>
									{/if}
								</td>
							</tr>
						{/each}
					</tbody>
				</table>
			</div>

			<!-- Mobile Cards -->
			<div class="space-y-3 sm:hidden">
				{#each defaultHours as row (row.weekday)}
					<div class="rounded-lg border p-4 transition-colors hover:bg-gray-50">
						<div class="mb-3 flex items-center justify-between">
							<div class="flex items-center gap-2">
								<span class="font-semibold text-gray-900">
									{weekdayLabel(row.weekday) === 'Mon'
										? 'Monday'
										: weekdayLabel(row.weekday) === 'Tue'
											? 'Tuesday'
											: weekdayLabel(row.weekday) === 'Wed'
												? 'Wednesday'
												: weekdayLabel(row.weekday) === 'Thu'
													? 'Thursday'
													: weekdayLabel(row.weekday) === 'Fri'
														? 'Friday'
														: weekdayLabel(row.weekday) === 'Sat'
															? 'Saturday'
															: 'Sunday'}
								</span>
							</div>
							<span
								class="inline-flex items-center rounded-full px-2.5 py-1 text-xs font-medium {row.is_open
									? 'bg-emerald-100 text-emerald-800'
									: 'bg-gray-100 text-gray-800'}"
							>
								<span
									class="mr-1.5 h-1.5 w-1.5 rounded-full {row.is_open
										? 'bg-emerald-600'
										: 'bg-gray-600'}"
								></span>
								{row.is_open ? 'Open' : 'Closed'}
							</span>
						</div>

						{#if row.is_open}
							<div class="grid grid-cols-2 gap-3 text-sm">
								<div>
									<div class="mb-1 text-xs text-gray-500">Opening</div>
									<div class="font-medium text-gray-900">{row.start_time}</div>
								</div>
								<div>
									<div class="mb-1 text-xs text-gray-500">Closing</div>
									<div class="font-medium text-gray-900">{row.end_time}</div>
								</div>
							</div>
							<div class="mt-3 border-t pt-3 text-xs text-gray-600">
								Total: <span class="font-medium text-gray-900"
									>{calculateHours(row.start_time, row.end_time)} hours</span
								>
							</div>
						{:else}
							<div class="text-sm text-gray-500">No hours scheduled for this day</div>
						{/if}
					</div>
				{/each}
			</div>
		</Card.Content>
	{:else}
		<!-- Skeleton loading -->
		<Card.Content class="space-y-4">
			<!-- Desktop Skeleton -->
			<div class="hidden w-full overflow-x-auto md:block">
				<table class="w-full table-auto border-collapse">
					<thead>
						<tr
							class="border-b bg-gray-50 text-left text-xs font-medium tracking-wider text-gray-600 uppercase"
						>
							<th class="px-4 py-3">Day</th>
							<th class="px-4 py-3 text-center">Status</th>
							<th class="px-4 py-3">Opening Time</th>
							<th class="px-4 py-3">Closing Time</th>
							<th class="px-4 py-3 text-right">Total Hours</th>
						</tr>
					</thead>
					<tbody class="divide-y divide-gray-200">
						{#each Array(7) as _, i (i)}
							<tr>
								<td class="px-4 py-4">
									<div class="flex items-center gap-2">
										<Skeleton class="h-8 w-8 rounded-full" />
										<Skeleton class="h-4 w-20" />
									</div>
								</td>
								<td class="px-4 py-4 text-center">
									<Skeleton class="mx-auto h-6 w-16 rounded-full" />
								</td>
								<td class="px-4 py-4">
									<Skeleton class="h-4 w-20" />
								</td>
								<td class="px-4 py-4">
									<Skeleton class="h-4 w-20" />
								</td>
								<td class="px-4 py-4 text-right">
									<Skeleton class="ml-auto h-4 w-12" />
								</td>
							</tr>
						{/each}
					</tbody>
				</table>
			</div>

			<!-- Mobile Skeleton -->
			<div class="space-y-3 md:hidden">
				{#each Array(7) as _, i (i)}
					<div class="rounded-lg border p-4">
						<div class="mb-3 flex items-center justify-between">
							<div class="flex items-center gap-2">
								<Skeleton class="h-10 w-10 rounded-full" />
								<Skeleton class="h-5 w-24" />
							</div>
							<Skeleton class="h-6 w-16 rounded-full" />
						</div>
						<div class="grid grid-cols-2 gap-3">
							<Skeleton class="h-12 w-full" />
							<Skeleton class="h-12 w-full" />
						</div>
					</div>
				{/each}
			</div>
		</Card.Content>
	{/if}
</Card.Root>

<!-- Default Hours Modal -->
<Modal.Root bind:open={showDefaultHoursModal}>
	<Modal.Content class="max-h-[90vh] max-w-sm overflow-y-auto md:max-w-lg">
		<Modal.Header>
			<Modal.Title class="text-lg font-semibold">Edit Default Working Hours</Modal.Title>
			<Modal.Description>
				Set the standard open and close times for your business.
			</Modal.Description>
		</Modal.Header>

		<div class="px-4 pb-4">
			<div class="w-full overflow-x-auto">
				<table class="w-full table-auto">
					<thead>
						<tr class="border-b text-left text-xs text-gray-500">
							<th class="py-2">Day</th>
							<th class="py-2">Open</th>
							<th class="py-2">Start</th>
							<th class="py-2">End</th>
						</tr>
					</thead>
					<tbody>
						{#each defaultHoursDraft as row (row.weekday)}
							<tr class="border-t">
								<td class="py-2 text-sm">{weekdayLabel(row.weekday)}</td>
								<td class="py-2">
									<Checkbox bind:checked={row.is_open} />
								</td>
								<td class="py-2">
									<select
										bind:value={row.start_time}
										disabled={!row.is_open}
										class="max-w-[70px] text-sm"
									>
										{#each Array(24) as _, hour}
											{#each TIME15 as min (min)}
												<option value="{String(hour).padStart(2, '0')}:{min}"
													>{String(hour).padStart(2, '0')}:{min}</option
												>
											{/each}
										{/each}
									</select>
								</td>
								<td class="py-2">
									<select
										bind:value={row.end_time}
										disabled={!row.is_open}
										class="max-w-[70px] text-sm"
									>
										{#each Array(24) as _, hour}
											{#each TIME15 as min (min)}
												<option value="{String(hour).padStart(2, '0')}:{min}"
													>{String(hour).padStart(2, '0')}:{min}</option
												>
											{/each}
										{/each}
									</select>
								</td>
							</tr>
						{/each}
					</tbody>
				</table>
			</div>
		</div>

		<Modal.Footer class="flex items-center justify-end gap-2">
			<Button
				variant="outline"
				onclick={() => {
					showDefaultHoursModal = false;
				}}
			>
				Cancel
			</Button>
			<Button onclick={() => (showSaveDefaultHoursAlert = true)} disabled={savingHours}>
				Save Defaults
			</Button>
		</Modal.Footer>
	</Modal.Content>
</Modal.Root>

<!-- Save Default Hours Confirmation -->
<AlertDialog.Root bind:open={showSaveDefaultHoursAlert}>
	<AlertDialog.Content class="z-60">
		<AlertDialog.Header>
			<AlertDialog.Title>Save default hours?</AlertDialog.Title>
			<AlertDialog.Description>
				Are you sure you want to save these default hours? This will affect future bookings.
			</AlertDialog.Description>
		</AlertDialog.Header>
		<AlertDialog.Footer>
			<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
			<AlertDialog.Action onclick={confirmSaveDefaultHours}>Continue</AlertDialog.Action>
		</AlertDialog.Footer>
	</AlertDialog.Content>
</AlertDialog.Root>
