<script lang="ts">
	import { Button } from '$lib/components/ui/button/index.js';
	import * as Card from '$lib/components/ui/card/index.js';
	import { Input } from '$lib/components/ui/input/index.js';
	import { Label } from '$lib/components/ui/label/index.js';
	import { Textarea } from '$lib/components/ui/textarea/index.js';
	import { Separator } from '$lib/components/ui/separator/index.js';
	import { CalendarDate, getLocalTimeZone, type DateValue } from '@internationalized/date';
	import { authStore } from '$lib/stores/auth.svelte';
	import { toast } from 'svelte-sonner';
	import { SvelteMap, SvelteDate } from 'svelte/reactivity';

	// Components
	import BookingActions from '$lib/components/booking/BookingActions.svelte';
	import BookingSummary from '$lib/components/booking/BookingSummary.svelte';
	import StepIndicator from '$lib/components/booking/StepIndicator.svelte';
	import DatePicker from '$lib/components/booking/DatePicker.svelte';
	import TimeSlotPicker from '$lib/components/booking/TimeSlotPicker.svelte';
	import ServiceSelector from '$lib/components/booking/ServiceSelector.svelte';
	import {
		extractBookedSlots,
		getLunchProtectionForSlots,
		type TimeSlot
	} from '$lib/lunchProtection';

	import type {
		Service,
		CustomerInfo,
		WorkingHoursDay,
		AvailableHoursDay
	} from '$lib/types/booking';

	// =============== State Management ===============
	let currentStep = $state<number>(1);
	let selectedServices = $state<Service[]>([]);
	let selectedDate = $state<CalendarDate | undefined>(undefined);
	let selectedTime = $state<string | null>(null);
	let customerInfo = $state<CustomerInfo>({
		firstName: '',
		lastName: '',
		email: '',
		phone: '',
		specialRequests: ''
	});
	let isSubmitting = $state(false);

	// =============== Services Management ===============
	let services = $state<Service[]>([]);
	let servicesLoading = $state(true);

	async function fetchServices() {
		servicesLoading = true;
		try {
			const response = await fetch('/api/services', {
				method: 'GET',
				headers: {
					'Content-Type': 'application/json',
					Authorization: `Bearer ${authStore.currentToken}`
				}
			});

			if (response.ok) {
				const data: Service[] = await response.json();
				services = data;
			} else {
				console.error('Failed to fetch services:', response.status);
				toast.error('Failed to load services');
			}
		} catch (err) {
			console.error('Error fetching services:', err);
			toast.error('Network error loading services');
		} finally {
			servicesLoading = false;
		}
	}

	// =============== ADD: Lunch Protection ===============
	const lunchProtectionStatus = $derived(() => {
		if (!selectedDate || !workingHours || !availableHours || selectedServices.length === 0) {
			return new Map();
		}

		const dateStr = selectedDate.toString();
		const dayWorkingHours = workingHours[dateStr];
		const dayAvailableHours = availableHours[dateStr];

		if (!dayWorkingHours?.isOpen || !dayAvailableHours?.slots) {
			return new Map();
		}

		// Extract existing bookings from the gap between working hours and available hours
		const existingBookings = extractBookedSlots(
			dayWorkingHours.startTime,
			dayWorkingHours.endTime,
			dayAvailableHours.slots
		);

		// Get lunch protection status for all slots
		return getLunchProtectionForSlots(
			dayWorkingHours.startTime,
			dayWorkingHours.endTime,
			existingBookings,
			getTotalDuration(),
			15, // 15 minute slot intervals
			false // User journey - requires 1h minimum
		);
	});

	// =============== Working Hours & Available Hours ===============
	let workingHours = $state<Record<
		string,
		{ isOpen: boolean; startTime: string; endTime: string }
	> | null>(null);

	let availableHours = $state<Record<
		string,
		{ isOpen: boolean; slots: Array<{ startTime: string; endTime: string }> }
	> | null>(null);

	let loadingWorkingHours = $state<boolean>(false);
	let loadingAvailableHours = $state<boolean>(false);

	const workingHoursCache = new SvelteMap<
		string,
		Record<string, { isOpen: boolean; startTime: string; endTime: string }>
	>();

	const availableHoursCache = new SvelteMap<
		string,
		Record<string, { isOpen: boolean; slots: Array<{ startTime: string; endTime: string }> }>
	>();

	$effect(() => {
		return () => {
			workingHoursCache.clear();
			availableHoursCache.clear();
		};
	});

	// Initialize date boundaries
	const today = new SvelteDate();
	const tomorrow = new SvelteDate(today);
	tomorrow.setDate(today.getDate() + 1);
	const maxDate = new SvelteDate();
	maxDate.setMonth(today.getMonth() + 6);

	// Create CalendarDate objects
	const minDate = new CalendarDate(today.getFullYear(), today.getMonth() + 1, today.getDate());
	const maxCalendarDate = new CalendarDate(
		maxDate.getFullYear(),
		maxDate.getMonth() + 1,
		maxDate.getDate()
	);

	let placeholder = $state<CalendarDate>(minDate);

	$effect(() => {
		fetchServices();
	});
	$effect(() => {
		const monthKey = `${placeholder.year}-${String(placeholder.month).padStart(2, '0')}`;
		if (!workingHoursCache.has(monthKey) || !availableHoursCache.has(monthKey)) {
			fetchHoursForMonth(placeholder);
		}
	});

	async function fetchHoursForMonth(date: CalendarDate) {
		const monthKey = `${date.year}-${String(date.month).padStart(2, '0')}`;

		if (workingHoursCache.has(monthKey) && availableHoursCache.has(monthKey)) {
			workingHours = workingHoursCache.get(monthKey)!;
			availableHours = availableHoursCache.get(monthKey)!;
			return;
		}

		loadingWorkingHours = true;
		loadingAvailableHours = true;

		try {
			const startOfMonth = new CalendarDate(date.year, date.month, 1);
			const endOfMonth = new CalendarDate(
				date.year,
				date.month,
				date.calendar.getDaysInMonth(date)
			);

			const startStr = startOfMonth.toString();
			const endStr = endOfMonth.toString();

			// Fetch working hours
			const workingHoursResponse = await fetch(
				`/api/scheduling/working-hours?start=${startStr}&end=${endStr}`
			);
			if (!workingHoursResponse.ok) {
				throw new Error(`HTTP error! status: ${workingHoursResponse.status}`);
			}

			const workingHoursData: Array<WorkingHoursDay> = await workingHoursResponse.json();
			const workingHoursMap: Record<
				string,
				{ isOpen: boolean; startTime: string; endTime: string }
			> = {};

			workingHoursData.forEach((day) => {
				workingHoursMap[day.date] = {
					isOpen: day.isOpen,
					startTime: day.startTime,
					endTime: day.endTime
				};
			});

			workingHoursCache.set(monthKey, workingHoursMap);
			workingHours = workingHoursMap;

			// Fetch available hours
			const availableHoursResponse = await fetch(
				`/api/scheduling/available-hours?start=${startStr}&end=${endStr}`
			);
			if (!availableHoursResponse.ok) {
				throw new Error(`HTTP error! status: ${availableHoursResponse.status}`);
			}

			const availableHoursData: Array<AvailableHoursDay> = await availableHoursResponse.json();
			const availableHoursMap: Record<
				string,
				{ isOpen: boolean; slots: Array<{ startTime: string; endTime: string }> }
			> = {};

			availableHoursData.forEach((day) => {
				availableHoursMap[day.date] = {
					isOpen: day.isOpen,
					slots: day.slots
				};
			});

			availableHoursCache.set(monthKey, availableHoursMap);
			availableHours = availableHoursMap;

			if (!selectedDate) {
				setDefaultSelectedDate(workingHoursMap);
			}
		} catch (error) {
			console.error('Failed to fetch hours:', error);
			if (!selectedDate) {
				selectedDate = minDate;
			}
		} finally {
			loadingWorkingHours = false;
			loadingAvailableHours = false;
		}
	}

	function setDefaultSelectedDate(
		hoursMap: Record<string, { isOpen: boolean; startTime: string; endTime: string }>
	) {
		const currentDate = new SvelteDate();
		const maxDateJs = new SvelteDate(
			maxCalendarDate.year,
			maxCalendarDate.month - 1,
			maxCalendarDate.day
		);

		const daysDifference = Math.floor(
			(maxDateJs.getTime() - currentDate.getTime()) / (1000 * 60 * 60 * 24)
		);
		const daysToCheck = Math.min(daysDifference, 180);

		for (let i = 1; i <= daysToCheck; i++) {
			const nextDate = new SvelteDate(currentDate);
			nextDate.setDate(currentDate.getDate() + i);
			const dateStr = nextDate.toISOString().split('T')[0];

			if (hoursMap[dateStr]?.isOpen) {
				selectedDate = new CalendarDate(
					nextDate.getFullYear(),
					nextDate.getMonth() + 1,
					nextDate.getDate()
				);
				// Also update placeholder to show the month with first available date
				placeholder = new CalendarDate(
					nextDate.getFullYear(),
					nextDate.getMonth() + 1,
					1 // First day of the month
				);
				break;
			}
		}

		if (!selectedDate) {
			const tomorrow = new SvelteDate();
			tomorrow.setDate(tomorrow.getDate() + 1);
			selectedDate = new CalendarDate(
				tomorrow.getFullYear(),
				tomorrow.getMonth() + 1,
				tomorrow.getDate()
			);
			placeholder = new CalendarDate(tomorrow.getFullYear(), tomorrow.getMonth() + 1, 1);
		}
	}

	// =============== Time Slot Generation ===============
	function calculateEndTime(startTime: string, durationMinutes: number): string {
		const [hours, minutes] = startTime.split(':').map(Number);
		const date = new SvelteDate();
		date.setHours(hours, minutes, 0, 0);
		date.setMinutes(date.getMinutes() + durationMinutes);
		const endHours = date.getHours().toString().padStart(2, '0');
		const endMinutes = date.getMinutes().toString().padStart(2, '0');
		return `${endHours}:${endMinutes}`;
	}

	function timeToMinutes(time: string): number {
		const [hours, minutes] = time.split(':').map(Number);
		return hours * 60 + minutes;
	}

	function calculatePreviousTime(time: string): string {
		const [hours, minutes] = time.split(':').map(Number);
		let totalMinutes = hours * 60 + minutes;
		totalMinutes -= 15;

		const prevHours = Math.floor(totalMinutes / 60);
		const prevMinutes = totalMinutes % 60;
		return `${String(prevHours).padStart(2, '0')}:${String(prevMinutes).padStart(2, '0')}`;
	}

	function generateAvailableTimeSlots(duration: number, date: CalendarDate | undefined): string[] {
		if (!date || !workingHours || !availableHours) {
			return [];
		}

		const dateStr = date.toString();
		const dayWorkingHours = workingHours[dateStr];
		const dayAvailableHours = availableHours[dateStr];

		if (
			!dayWorkingHours ||
			!dayWorkingHours.isOpen ||
			!dayAvailableHours ||
			!dayAvailableHours.slots
		) {
			return [];
		}

		const slots: string[] = [];
		const now = new SvelteDate();
		const today = new CalendarDate(now.getFullYear(), now.getMonth() + 1, now.getDate());
		const isToday = date.compare(today) === 0;

		for (const slot of dayAvailableHours.slots) {
			const [startHour, startMinute] = slot.startTime.split(':').map(Number);
			const [endHour, endMinute] = slot.endTime.split(':').map(Number);

			let startTotalMinutes = startHour * 60 + startMinute;
			const endTotalMinutes = endHour * 60 + endMinute;

			if (isToday) {
				const currentMinutes = now.getHours() * 60 + now.getMinutes();
				const minimumStartMinutes = currentMinutes + 120;
				startTotalMinutes = Math.max(startTotalMinutes, minimumStartMinutes);
			}

			for (let minutes = startTotalMinutes; minutes < endTotalMinutes; minutes += 15) {
				const slotEndMinutes = minutes + duration;

				if (slotEndMinutes <= endTotalMinutes) {
					const hour = Math.floor(minutes / 60);
					const minute = minutes % 60;
					const timeStr = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;
					slots.push(timeStr);
				}
			}
		}

		return slots;
	}

	function generateGroupedTimeSlots(
		duration: number,
		date: CalendarDate | undefined
	): Array<{
		type: 'available' | 'unavailable';
		startTime: string;
		endTime: string;
		isGrouped?: boolean;
	}> {
		if (!date || !workingHours) {
			return [];
		}

		const dateStr = date.toString();
		const dayWorkingHours = workingHours[dateStr];

		if (!dayWorkingHours || !dayWorkingHours.isOpen) {
			return [];
		}

		const groupedSlots: Array<{
			type: 'available' | 'unavailable';
			startTime: string;
			endTime: string;
			isGrouped?: boolean;
		}> = [];
		const [startHour, startMinute] = dayWorkingHours.startTime.split(':').map(Number);
		const [endHour, endMinute] = dayWorkingHours.endTime.split(':').map(Number);

		let startTotalMinutes = startHour * 60 + startMinute;
		const endTotalMinutes = endHour * 60 + endMinute;

		const now = new SvelteDate();
		const today = new CalendarDate(now.getFullYear(), now.getMonth() + 1, now.getDate());
		const isToday = date.compare(today) === 0;

		if (isToday) {
			const currentMinutes = now.getHours() * 60 + now.getMinutes();
			const minimumStartMinutes = currentMinutes + 120;
			startTotalMinutes = Math.max(startTotalMinutes, minimumStartMinutes);
		}

		const availableSlots = generateAvailableTimeSlots(duration, date);

		let currentUnavailableStart: string | null = null;
		let lastAvailableEndTime: string | null = null;

		for (let minutes = startTotalMinutes; minutes < endTotalMinutes; minutes += 15) {
			const hour = Math.floor(minutes / 60);
			const minute = minutes % 60;
			const timeStr = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;

			const isAvailable = availableSlots.includes(timeStr);

			if (isAvailable) {
				if (currentUnavailableStart !== null) {
					// Use the end time of the last available slot as the start of unavailable period
					const unavailableStartTime = lastAvailableEndTime || currentUnavailableStart;
					const groupEndTime = calculatePreviousTime(timeStr);
					groupedSlots.push({
						type: 'unavailable',
						startTime: unavailableStartTime,
						endTime: groupEndTime,
						isGrouped: true
					});
					currentUnavailableStart = null;
				}

				const slotEndTime = calculateEndTime(timeStr, duration);
				lastAvailableEndTime = slotEndTime;
				groupedSlots.push({
					type: 'available',
					startTime: timeStr,
					endTime: slotEndTime
				});

				if (timeToMinutes(slotEndTime) >= endTotalMinutes) {
					break;
				}
			} else {
				if (currentUnavailableStart === null) {
					currentUnavailableStart = timeStr;
				}
			}
		}

		if (currentUnavailableStart !== null) {
			const lastAvailableSlot = groupedSlots.filter((s) => s.type === 'available').pop();
			const lastAvailableEnd = lastAvailableSlot ? timeToMinutes(lastAvailableSlot.endTime) : 0;

			const unavailableStartMinutes = timeToMinutes(currentUnavailableStart);

			if (unavailableStartMinutes < endTotalMinutes && lastAvailableEnd < endTotalMinutes) {
				// Use the end time of the last available slot for the final unavailable period
				const unavailableStartTime = lastAvailableSlot
					? lastAvailableSlot.endTime
					: currentUnavailableStart;
				groupedSlots.push({
					type: 'unavailable',
					startTime: unavailableStartTime,
					endTime: dayWorkingHours.endTime,
					isGrouped: true
				});
			}
		}

		return groupedSlots;
	}

	// =============== Date Availability Check ===============
	function isDateUnavailable(date: DateValue): boolean {
		if (!(date instanceof CalendarDate)) {
			return true;
		}

		if (date.compare(minDate) < 0 || date.compare(maxCalendarDate) > 0) {
			return true;
		}

		if (!workingHours) return true;

		const dateStr = date.toString();
		const dayHours = workingHours[dateStr];

		if (!dayHours) return true;
		if (!dayHours.isOpen) return true;

		// If no services selected, don't check availability slots
		// This allows calendar to show open/closed days
		if (selectedServices.length === 0) {
			return false; // Show all working days as available
		}

		const duration = getTotalDuration();
		const availableSlots = generateAvailableTimeSlots(duration, date);
		if (availableSlots.length === 0) return true;

		return false;
	}

	// =============== Helper Functions ===============
	function getTotalDuration() {
		return selectedServices.reduce(
			(total, service: Service) => total + service.duration_minutes,
			0
		);
	}

	function getTotalPrice() {
		return selectedServices.reduce((total, service: Service) => total + service.price, 0);
	}

	function toggleService(service: Service) {
		const index = selectedServices.findIndex((s) => s.id === service.id);
		const wasSelected = index >= 0;

		if (wasSelected) {
			selectedServices = selectedServices.filter((s) => s.id !== service.id);
		} else {
			selectedServices = [...selectedServices, service];
		}

		// Only clear if we're on the date/time selection step
		if (currentStep === 2 && selectedDate) {
			const monthKey = `${selectedDate.year}-${String(selectedDate.month).padStart(2, '0')}`;
			availableHoursCache.delete(monthKey); // Only delete current month
			fetchHoursForMonth(selectedDate);
		}

		selectedTime = null;
	}

	function formatDuration(minutes: number): string {
		const hours = Math.floor(minutes / 60);
		const remainingMinutes = minutes % 60;

		if (hours === 0) {
			return `${remainingMinutes} minutes`;
		} else if (remainingMinutes === 0) {
			return `${hours} ${hours === 1 ? 'hour' : 'hours'}`;
		} else {
			return `${hours} ${hours === 1 ? 'hour' : 'hours'} ${remainingMinutes} minutes`;
		}
	}

	function getDayWithOrdinal(date: CalendarDate): string {
		const monthName = new SvelteDate(date.year, date.month - 1, date.day).toLocaleDateString(
			'en-GB',
			{
				month: 'long'
			}
		);
		const day = date.day;
		if (day > 3 && day < 21) return monthName + ' ' + day + 'th';
		switch (day % 10) {
			case 1:
				return monthName + ' ' + day + 'st';
			case 2:
				return monthName + ' ' + day + 'nd';
			case 3:
				return monthName + ' ' + day + 'rd';
			default:
				return monthName + ' ' + day + 'th';
		}
	}

	// =============== Derived Values ===============
	const formattedTotalDuration = $derived(formatDuration(getTotalDuration()));
	const groupedTimeSlots = $derived(
		currentStep === 2 && selectedServices.length > 0 && selectedDate
			? generateGroupedTimeSlots(getTotalDuration(), selectedDate)
			: []
	);
	const formattedSelectedDate = $derived(
		selectedDate ? getDayWithOrdinal(selectedDate) : undefined
	);

	// =============== Navigation ===============
	function nextStep() {
		if (currentStep < 4) {
			currentStep++;
			setTimeout(() => {
				window.scrollTo({ top: 0, behavior: 'smooth' });
			}, 50);
		}
	}

	function prevStep() {
		if (currentStep > 1) {
			currentStep--;
			setTimeout(() => {
				window.scrollTo({ top: 0, behavior: 'smooth' });
			}, 50);
		}
	}

	// =============== Validation ===============
	const canProceedStep1 = $derived(selectedServices.length > 0);
	const canProceedStep2 = $derived(!!(selectedDate && selectedTime));
	const canProceedStep3 = $derived(
		authStore.isAuthenticated
			? !!(
					authStore.currentUser?.firstName &&
					authStore.currentUser?.lastName &&
					authStore.currentUser?.email &&
					authStore.currentUser?.phone
				)
			: !!(
					customerInfo.firstName &&
					customerInfo.lastName &&
					customerInfo.email &&
					customerInfo.phone
				)
	);

	// =============== Submission ===============
	async function submitBooking() {
		isSubmitting = true;
		try {
			console.log('Submitting booking:', {
				services: selectedServices,
				date: selectedDate,
				time: selectedTime,
				customer: authStore.isAuthenticated ? authStore.currentUser : customerInfo
			});

			toast.success('Booking submitted successfully!');
		} catch (error) {
			console.error('Booking submission failed:', error);
			toast.error('Failed to submit booking. Please try again.');
		} finally {
			isSubmitting = false;
		}
	}
</script>

<div class="mx-auto max-w-4xl p-6">
	<div class="mb-8 text-center">
		<h1 class="mb-2 text-3xl font-bold">Book Your Appointment</h1>
		<p class="text-gray-600">Professional beauty treatments in a calm and friendly environment</p>
	</div>

	<StepIndicator {currentStep} />

	<!-- Step 1: Service Selection -->
	{#if currentStep === 1}
		<Card.Root>
			<Card.Header>
				<Card.Title>Choose Your Services</Card.Title>
				<Card.Description>Select one or more treatments for your appointment</Card.Description>
			</Card.Header>
			<Card.Content class="space-y-4">
				<ServiceSelector
					{services}
					selected={selectedServices}
					loading={servicesLoading}
					ontoggle={toggleService}
				/>

				{#if selectedServices.length > 0}
					<div class="rounded-lg bg-gray-50 p-4">
						<h4 class="mb-2 font-semibold">Selected Services</h4>
						<div class="space-y-2">
							{#each selectedServices as service (service.id)}
								<div class="flex justify-between text-sm">
									<span>{service.name}</span>
									<span>{service.duration_minutes} mins • £{service.price}</span>
								</div>
							{/each}
							<Separator class="my-2" />
							<div class="flex justify-between text-sm font-semibold">
								<span>Estimated Duration:</span>
								<span>{formattedTotalDuration}</span>
							</div>
							<div class="flex justify-between text-sm font-semibold">
								<span>Total Cost:</span>
								<span>£{getTotalPrice()}</span>
							</div>
						</div>
					</div>
				{/if}
			</Card.Content>
			<Card.Footer class="flex justify-end">
				<BookingActions
					canBack={false}
					canNext={canProceedStep1}
					nextLabel="Next: Select Date & Time"
					on:next={nextStep}
				/>
			</Card.Footer>
		</Card.Root>
	{/if}

	<!-- Step 2: Date & Time Selection -->
	{#if currentStep === 2}
		<Card.Root>
			<Card.Header>
				<Card.Title>Choose Date & Time</Card.Title>
				<Card.Description>
					{selectedServices.map((s) => s.name).join(', ')} • {formattedTotalDuration} total • £{getTotalPrice()}
				</Card.Description>
			</Card.Header>
			<Card.Content class="p-0">
				<Card.Root class="gap-0 border-0 p-0">
					<Card.Content class="relative p-0 md:pr-56">
						{#if loadingWorkingHours}
							<div class="flex items-center justify-center p-6">
								<p>Loading available dates...</p>
							</div>
						{:else}
							<DatePicker
								date={selectedDate}
								{placeholder}
								minValue={minDate}
								maxValue={maxCalendarDate}
								{isDateUnavailable}
								onchange={(newDate) => {
									selectedDate = newDate;
									selectedTime = null;
								}}
								onPlaceholderChange={(newPlaceholder) => {
									placeholder = newPlaceholder;
								}}
							/>
						{/if}

						{#if loadingAvailableHours}
							<div
								class="absolute inset-y-0 right-0 flex w-56 items-center justify-center border-l p-6"
							>
								<p class="text-sm text-gray-500">Loading times...</p>
							</div>
						{:else}
							<TimeSlotPicker
								date={selectedDate}
								{groupedTimeSlots}
								{selectedTime}
								formattedDate={formattedSelectedDate}
								onselect={(time) => {
									selectedTime = time;
								}}
								lunchProtectionStatus={lunchProtectionStatus()}
							/>
						{/if}
					</Card.Content>
				</Card.Root>
			</Card.Content>

			<!-- Mobile appointment summary -->
			<div class="border-t px-6 py-4 text-center text-sm md:hidden">
				{#if selectedDate && selectedTime}
					Appointment for
					<span class="font-medium">
						{selectedDate.toDate(getLocalTimeZone()).toLocaleDateString('en-US', {
							weekday: 'long',
							day: 'numeric',
							month: 'short'
						})}
					</span>
					<br />at <span class="font-medium">{selectedTime}</span>
				{:else}
					Select a date and time
				{/if}
			</div>

			<Card.Footer class="flex justify-between border-t px-6 !py-5">
				<Button variant="outline" onclick={prevStep}>Back</Button>
				<div class="flex items-center space-x-4">
					<!-- Desktop appointment summary -->
					<div class="hidden text-sm md:block">
						{#if selectedDate && selectedTime}
							Appointment for
							<span class="font-medium">
								{selectedDate.toDate(getLocalTimeZone()).toLocaleDateString('en-US', {
									weekday: 'long',
									day: 'numeric',
									month: 'short'
								})}
							</span>
							at <span class="font-medium">{selectedTime}</span>
						{:else}
							Select a date and time
						{/if}
					</div>
					<Button disabled={!canProceedStep2} onclick={nextStep}>Next: Your Details</Button>
				</div>
			</Card.Footer>
		</Card.Root>
	{/if}

	<!-- Step 3: Customer Details -->
	{#if currentStep === 3}
		<Card.Root>
			<Card.Header>
				<Card.Title>Your Details</Card.Title>
				<Card.Description>Please confirm your contact information</Card.Description>
			</Card.Header>
			<Card.Content class="space-y-6">
				<BookingSummary
					services={selectedServices}
					date={selectedDate}
					time={selectedTime}
					showCustomer={false}
				/>

				{#if !authStore.isAuthenticated}
					<p class="mb-4 text-center text-sm text-yellow-600">
						You are checking out as a guest, so you will miss out on a loyalty stamp. Please login
						for full membership benefits.
					</p>

					<div class="grid gap-4 md:grid-cols-2">
						<div class="space-y-2">
							<Label for="firstName">First Name *</Label>
							<Input
								id="firstName"
								bind:value={customerInfo.firstName}
								placeholder="Enter your first name"
							/>
						</div>
						<div class="space-y-2">
							<Label for="lastName">Last Name *</Label>
							<Input
								id="lastName"
								bind:value={customerInfo.lastName}
								placeholder="Enter your last name"
							/>
						</div>
						<div class="space-y-2">
							<Label for="email">Email *</Label>
							<Input
								id="email"
								type="email"
								bind:value={customerInfo.email}
								placeholder="Enter your email"
							/>
						</div>
						<div class="space-y-2">
							<Label for="phone">Phone Number *</Label>
							<Input
								id="phone"
								type="tel"
								bind:value={customerInfo.phone}
								placeholder="Enter your phone number"
							/>
						</div>
					</div>
				{/if}

				<div class="space-y-2">
					<Label for="requests">Special Requests (Optional)</Label>
					<Textarea
						id="requests"
						bind:value={customerInfo.specialRequests}
						placeholder="Any allergies, preferences, or special requirements..."
						rows={3}
					/>
				</div>

				<div class="text-sm text-gray-600">
					{#if !authStore.isAuthenticated}
						<p>* Required fields</p>
					{/if}
					<p class="mt-2">
						By booking, you agree to our Terms & Conditions and Privacy Policy. We'll send you
						appointment reminders via email and/or SMS.
					</p>
				</div>
			</Card.Content>
			<Card.Footer class="flex justify-between">
				<Button variant="outline" onclick={prevStep}>Back</Button>
				<Button
					disabled={!canProceedStep3}
					onclick={nextStep}
					class="bg-primary text-primary-foreground"
				>
					Next: Payment
				</Button>
			</Card.Footer>
		</Card.Root>
	{/if}

	<!-- Step 4: Payment (complete) -->
	{#if currentStep === 4}
		<Card.Root>
			<Card.Header>
				<Card.Title>Payment Confirmation</Card.Title>
				<Card.Description>Review and complete your booking</Card.Description>
			</Card.Header>
			<Card.Content class="space-y-6">
				<BookingSummary
					services={selectedServices}
					date={selectedDate}
					time={selectedTime}
					customer={authStore.isAuthenticated
						? {
								firstName: authStore.currentUser?.firstName ?? '',
								lastName: authStore.currentUser?.lastName ?? '',
								email: authStore.currentUser?.email ?? '',
								phone: authStore.currentUser?.phone ?? '',
								specialRequests: customerInfo.specialRequests
							}
						: customerInfo}
					showCustomer={true}
				/>

				<!-- Payment form placeholder -->
				<div class="rounded-lg bg-white p-6">
					<h2 class="mb-4 text-2xl font-semibold">Payment</h2>
					<p class="text-gray-600">Square payment integration will be added here.</p>
				</div>
			</Card.Content>
			<Card.Footer class="flex justify-between">
				<Button variant="outline" onclick={prevStep}>Back</Button>
				<Button
					disabled={!canProceedStep3 || isSubmitting}
					onclick={submitBooking}
					class="bg-primary text-primary-foreground"
				>
					{isSubmitting ? 'Processing...' : 'Complete Booking'}
				</Button>
			</Card.Footer>
		</Card.Root>
	{/if}
</div>
