<script lang="ts">
	import { authStore } from '$lib/stores/auth.svelte';
	import { apiFetch } from '$lib/utils/api';
	import { toast } from 'svelte-sonner';
	import { SvelteDate } from 'svelte/reactivity';
	import * as Modal from '$lib/components/ui/dialog';
	import { Button } from '$lib/components/ui/button';
	import { Checkbox } from '$lib/components/ui/checkbox';
	import PolicyPopover from '$lib/components/ui/policyPopover.svelte';
	import ApprovalModal from '$lib/components/admin/ApprovalModal.svelte';
	import RescheduleModal from '$lib/components/admin/RescheduleModal.svelte';
	import { formatDuration, formatDateTime, calculateAge } from '$lib/utils/format';
	import { formatUserName } from '$lib/utils/nameDisplay';
	import { computeBalanceDue } from '$lib/utils/booking';
	import { POLICY } from '$lib/constants/policy';
	import type { Booking, BookingService, BookingDiscount, Payment } from '$lib/types/booking';
	import type { Refund } from '$lib/types/index';

	interface Props {
		open: boolean;
		bookingId: string;
		onReschedule?: () => void;
	}

	let { open = $bindable(), bookingId, onReschedule }: Props = $props();

	let selectedBooking = $state<Booking | null>(null);
	let showApprovalModal = $state(false);
	let showRescheduleModal = $state(false);
	let showCancelModal = $state(false);
	let forgiveFeesCancel = $state(false);
	let forgiveNoShowCancel = $state(false);
	let cancelling = $state(false);

	// Derived values for cancel confirmation
	const totalPaid = $derived(
		(selectedBooking?.payments ?? [])
			.filter((p) => p.payment_method !== 'discount' && p.status === 'completed')
			.reduce((sum, p) => sum + p.amount, 0)
	);
	const totalRefunds = $derived(
		(selectedBooking?.refunds ?? [])
			.filter((r) => r.status === 'completed')
			.reduce((sum, r) => sum + r.amount, 0)
	);
	const balanceDue = $derived(selectedBooking ? computeBalanceDue(selectedBooking) : 0);
	const hoursUntilAppt = $derived(
		selectedBooking
			? (new SvelteDate(selectedBooking.start_time).getTime() - new SvelteDate().getTime()) /
					(1000 * 60 * 60)
			: Infinity
	);
	const protectedDeposit = $derived(
		selectedBooking
			? Math.min(totalPaid, selectedBooking.total_amount * POLICY.PROTECTED_DEPOSIT_MAX_PCT)
			: 0
	);
	const estimatedRefund = $derived(
		forgiveFeesCancel
			? totalPaid
			: hoursUntilAppt > POLICY.FULL_REFUND_THRESHOLD_HOURS
				? totalPaid
				: hoursUntilAppt >= POLICY.PARTIAL_REFUND_THRESHOLD_HOURS
					? Math.max(0, totalPaid - protectedDeposit)
					: 0
	);
	async function handleAdminCancel() {
		if (!selectedBooking) return;
		cancelling = true;
		try {
			const body: Record<string, unknown> = {};
			if (forgiveFeesCancel) body.forgive_fees = true;
			if (forgiveNoShowCancel) body.forgive_noshow = true;
			const response = await apiFetch(`/api/admin/bookings/${selectedBooking.id}/cancel`, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify(body)
			});
			if (response.ok) {
				toast.success('Booking cancelled');
				showCancelModal = false;
				fetchBookingDetails();
			} else {
				const text = await response.text();
				toast.error('Failed to cancel: ' + text);
			}
		} catch (_err) {
			toast.error('Network error');
		} finally {
			cancelling = false;
		}
	}

	// Calculate total duration from services
	// IMPORTANT: Use override_duration_minutes when present — services may have been
	// customised at booking time (discounts, extended sessions). Showing base values
	// misleads admins about what was actually booked.
	const totalDuration = $derived(
		selectedBooking?.services?.reduce(
			(sum, service) => sum + (service.override_duration_minutes ?? service.duration_minutes ?? 0),
			0
		) || 0
	);

	async function fetchBookingDetails() {
		if (!bookingId) return;

		try {
			const response = await apiFetch(`/api/admin/bookings/${bookingId}`, {
				method: 'GET',
				headers: {
					'Content-Type': 'application/json'
				}
			});

			if (response.ok) {
				const data = await response.json();

				selectedBooking = {
					id: data.id,
					start_time: data.start_time,
					status: data.status,
					notes: data.notes,
					created_at: data.created_at,
					updated_at: data.updated_at,
					created_by: data.created_by,
					created_by_name: data.created_by_name,
					out_of_hours: data.out_of_hours ?? false,

					// Deposit fields
					deposit_required: data.deposit_required ?? false,
					deposit_amount: data.deposit_amount,
					deposit_paid: data.deposit_paid ?? false,
					deposit_deadline: data.deposit_deadline,

					// User
					user: data.user
						? {
								id: data.user.id,
								first_name: data.user.first_name,
								last_name: data.user.last_name,
								full_name: data.user.full_name,
								email: data.user.email,
								phone: data.user.phone,
								profile_pic_url: data.user.profile_pic_url,
								date_of_birth: data.user.date_of_birth,
								account_role: data.user.account_role,
								loyalty_stamps: data.user.loyalty_stamps,
								referral_code: data.user.referral_code,
								referral_code_uses: data.user.referral_code_uses,
								created_at: data.user.created_at,
								notes: data.user.notes,
								previous_first_name: data.user.previous_first_name,
								previous_last_name: data.user.previous_last_name
							}
						: undefined,

					// Services
					services: (data.services || []).map((s: BookingService) => ({
						booking_id: s.booking_id,
						service_id: s.service_id,
						service_name: s.service_name,
						service_description: s.service_description,
						price: s.price,
						duration_minutes: s.duration_minutes,
						override_price: s.override_price,
						override_duration_minutes: s.override_duration_minutes
					})),

					// Payments
					payments: (data.payments || []).map((p: Payment) => ({
						id: p.id,
						booking_id: p.booking_id,
						payment_type: p.payment_type,
						payment_method: p.payment_method,
						vendor_code: p.vendor_code,
						invoice_number: p.invoice_number,
						status: p.status,
						amount: p.amount,
						is_vat_applicable: p.is_vat_applicable,
						vat_rate: p.vat_rate,
						vat_amount: p.vat_amount,
						net_amount: p.net_amount,
						created_at: p.created_at,
						updated_at: p.updated_at,
						created_by: p.created_by
					})),

					// Refunds
					refunds: (data.refunds || []).map((r: Refund) => ({
						id: r.id,
						payment_id: r.payment_id,
						booking_id: r.booking_id,
						amount: r.amount,
						square_refund_id: r.square_refund_id,
						status: r.status,
						reason: r.reason,
						created_by: r.created_by,
						created_at: r.created_at
					})),

					// Financials
					total_amount: data.total_amount || 0,
					amount_paid: data.amount_paid || 0,
					amount_due: data.amount_due || 0,
					duration_minutes: data.duration_minutes || 0,
					discounts: data.discounts || []
				};
			} else {
				const text = await response.text();
				toast.error('Failed to load booking details: ' + text);
			}
		} catch (_err) {
			console.error('Network error loading booking details:', _err);
			toast.error('Network error loading booking details');
		}
	}

	function getPaymentName(
		payment: Payment,
		index: number,
		payments: Payment[] | undefined,
		discounts: BookingDiscount[] | undefined
	): string {
		if (payment.payment_method === 'online_square') return 'Online Card';
		if (payment.payment_method === 'in_person_card') return 'Card Machine';
		if (payment.payment_method === 'cash') return 'Cash';
		if (payment.payment_method === 'giftcard') return 'Gift Card';
		if (payment.payment_method === 'discount') {
			const discountPaymentsBefore = (payments ?? [])
				.slice(0, index)
				.filter((p) => p.payment_method === 'discount').length;
			const discountList = (discounts ?? []).filter((d) => d.discount_amount > 0.01);
			if (discountList[discountPaymentsBefore]) {
				const d = discountList[discountPaymentsBefore];
				if (d.discount_source === 'loyalty') return 'Loyalty Stamp Card (10% Off)';
				if (d.campaign_name) return `${d.campaign_name}`;
				return 'Promo Campaign Discount';
			}
			return 'Discount';
		}
		return (payment.payment_method as string)
			.replace(/_/g, ' ')
			.replace(/\b\w/g, (c) => c.toUpperCase());
	}

	$effect(() => {
		if (open && bookingId) {
			fetchBookingDetails();
		}
	});
</script>

<Modal.Root bind:open>
	<Modal.Content
		class="!z-[60] max-h-[90vh] max-w-[calc(100%-2rem)] overflow-y-auto sm:max-w-md md:max-w-3xl"
	>
		<Modal.Header>
			<div class="flex items-center justify-between">
				<div>
					<Modal.Title class="text-lg font-semibold">Booking Details</Modal.Title>
					{#if selectedBooking}
						<div class="mt-1 text-sm text-gray-500">ID: {selectedBooking.id}</div>
					{/if}
				</div>
				{#if selectedBooking}
					{@const isConfirmedOrLater = ['confirmed', 'in_progress', 'completed'].includes(
						selectedBooking.status
					)}

					{#if selectedBooking.status === 'pending'}
						<div class="flex items-center gap-2">
							<Button
								onclick={() => (showApprovalModal = true)}
								class="bg-emerald-600 hover:bg-emerald-700"
							>
								<svg
									xmlns="http://www.w3.org/2000/svg"
									class="mr-2 h-4 w-4"
									viewBox="0 0 20 20"
									fill="currentColor"
								>
									<path
										fill-rule="evenodd"
										d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
										clip-rule="evenodd"
									/>
								</svg>
								Approve Booking
							</Button>

							<span
								class="inline-flex items-center rounded-full bg-yellow-100 px-3 py-1 text-sm
								font-medium text-yellow-800"
							>
								Pending
							</span>

							<!-- Deposit Badge for pending -->
							{#if selectedBooking.deposit_required}
								<span
									class="inline-flex items-center rounded-full bg-blue-100 px-3 py-1 text-sm font-medium text-blue-800"
								>
									Will Require Deposit
								</span>
							{/if}
						</div>
					{:else if isConfirmedOrLater && selectedBooking.deposit_required}
						<!-- Deposit Badge for confirmed+ -->
						<div class="flex items-center gap-2">
							<span
								class="inline-flex items-center rounded-full px-3 py-1 text-sm font-medium
								{selectedBooking.status === 'completed'
									? 'bg-green-100 text-green-800'
									: selectedBooking.status === 'in_progress'
										? 'bg-blue-100 text-blue-800'
										: 'bg-emerald-100 text-emerald-800'}"
							>
								{selectedBooking.status.replace('_', ' ')}
							</span>
							<span
								class="inline-flex items-center rounded-full px-3 py-1 text-sm font-medium
							{selectedBooking.deposit_paid ? 'bg-green-100 text-green-800' : 'bg-orange-100 text-orange-800'}"
							>
								{selectedBooking.deposit_paid ? 'Deposit Paid' : 'Deposit Due'}
							</span>
						</div>
					{/if}

					{#if selectedBooking.out_of_hours}
						<div class="flex items-center gap-2">
							<span
								class="inline-flex items-center rounded-full bg-red-100 px-3 py-1 text-sm font-medium text-red-800"
							>
								<svg
									xmlns="http://www.w3.org/2000/svg"
									class="mr-1 h-3.5 w-3.5"
									viewBox="0 0 20 20"
									fill="currentColor"
								>
									<path
										fill-rule="evenodd"
										d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z"
										clip-rule="evenodd"
									/>
								</svg>
								Out-of-hours
							</span>
						</div>
					{/if}
				{/if}
			</div>
		</Modal.Header>

		{#if selectedBooking}
			<div class="space-y-6 px-4 pb-4">
				<!-- Appointment Details -->
				<div class="rounded-lg border border-gray-200 bg-gray-50 p-4">
					<h3 class="mb-3 text-sm font-semibold tracking-wide text-gray-600 uppercase">
						Appointment Details
					</h3>
					<div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
						<div>
							<div class="text-xs text-gray-500">Scheduled Date & Time</div>
							<div class="font-medium">
								{formatDateTime(selectedBooking.start_time)}
							</div>
						</div>
						<div>
							<div class="text-xs text-gray-500">Duration</div>
							<div class="font-medium">{formatDuration(totalDuration)}</div>
						</div>
						<div>
							<div class="text-xs text-gray-500">Created</div>
							<div class="text-sm">
								{formatDateTime(selectedBooking.created_at)}
							</div>
						</div>
						{#if selectedBooking.created_by_name}
							<div>
								<div class="text-xs text-gray-500">Booked In By</div>
								<div class="text-sm">
									{selectedBooking.created_by === authStore.currentUser?.id
										? 'yourself'
										: selectedBooking.created_by_name}
								</div>
							</div>
						{/if}
					</div>
					{#if selectedBooking.notes}
						<div class="mt-3 rounded-md border border-amber-200 bg-amber-50 p-3">
							<div class="mb-1 text-xs font-semibold text-amber-800">Booking Notes</div>
							<div class="text-sm text-amber-900">{selectedBooking.notes}</div>
						</div>
					{/if}
				</div>

				<!-- Deposit Info (moved to Financial Summary) -->

				<!-- Services -->
				{#if selectedBooking.services && selectedBooking.services.length > 0}
					<div class="rounded-lg border border-gray-200 bg-gray-50 p-4">
						<h3 class="mb-3 text-sm font-semibold tracking-wide text-gray-600 uppercase">
							Services
						</h3>
						<div class="space-y-3">
							{#each selectedBooking.services as service, index (index)}
								<div class="rounded-md border border-gray-300 bg-white p-3">
									<div class="font-medium">{service.service_name || '—'}</div>
									{#if service.service_description}
										<div class="mt-1 text-sm text-gray-600">{service.service_description}</div>
									{/if}
									<div class="mt-2 flex items-center justify-between text-sm">
										<span class="text-gray-600"
											>{formatDuration(
												service.override_duration_minutes ?? service.duration_minutes ?? 0
											)}</span
										>
										<span class="font-semibold"
											>£{(service.override_price ?? service.price ?? 0).toFixed(2)}</span
										>
									</div>
								</div>
							{/each}
						</div>
					</div>
				{/if}

				<!-- Customer Information -->
				<div class="rounded-lg border border-gray-200 bg-gray-50 p-4">
					<h3 class="mb-3 text-sm font-semibold tracking-wide text-gray-600 uppercase">
						Customer Information
					</h3>

					<div class="mb-4 flex items-center gap-4">
						{#if selectedBooking.user?.profile_pic_url}
							<img
								src={selectedBooking.user.profile_pic_url}
								alt={formatUserName(
									selectedBooking.user.full_name,
									selectedBooking.user.previous_first_name,
									selectedBooking.user.previous_last_name
								)}
								class="h-16 w-16 rounded-full object-cover ring-4 ring-blue-200"
							/>
						{/if}
						<div>
							<div class="text-lg font-semibold">
								{formatUserName(
									selectedBooking.user?.full_name || '—',
									selectedBooking.user?.previous_first_name,
									selectedBooking.user?.previous_last_name
								)}
							</div>
							{#if selectedBooking.user?.date_of_birth}
								<div class="text-sm text-gray-500">
									{calculateAge(selectedBooking.user.date_of_birth)} years old
								</div>
							{/if}
						</div>
					</div>

					<div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
						<div>
							<div class="text-xs text-gray-500">Email</div>
							{#if selectedBooking.user?.email}
								<a
									href="mailto:{selectedBooking.user.email}"
									class="font-medium break-words text-blue-600 hover:underline"
									>{selectedBooking.user.email}</a
								>
							{:else}
								<div class="font-medium">—</div>
							{/if}
						</div>
						<div>
							<div class="text-xs text-gray-500">Phone</div>
							{#if selectedBooking.user?.phone}
								<a
									href="tel:{selectedBooking.user.phone}"
									class="font-medium text-blue-600 hover:underline">{selectedBooking.user.phone}</a
								>
							{:else}
								<div class="font-medium">—</div>
							{/if}
						</div>
						{#if selectedBooking.user?.referral_code}
							<div>
								<div class="text-xs text-gray-500">Referral Code</div>
								<div class="flex items-center gap-1.5">
									<code class="rounded bg-gray-200 px-1.5 py-0.5 font-mono text-sm font-medium">
										{selectedBooking.user.referral_code}
									</code>
									<button
										type="button"
										title="Copy referral code"
										class="inline-flex items-center justify-center rounded p-1 text-gray-500 transition-colors hover:bg-gray-200 hover:text-gray-700"
										onclick={() => {
											const code = selectedBooking?.user?.referral_code;
											if (code) {
												navigator.clipboard.writeText(code);
												toast.success('Referral code copied');
											}
										}}
									>
										<svg
											xmlns="http://www.w3.org/2000/svg"
											class="h-4 w-4"
											viewBox="0 0 24 24"
											fill="none"
											stroke="currentColor"
											stroke-width="2"
										>
											<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
											<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
										</svg>
									</button>
								</div>
							</div>
						{/if}
						{#if selectedBooking.user?.referral_code_uses !== undefined && selectedBooking.user?.referral_code_uses !== null}
							<div>
								<div class="text-xs text-gray-500">Referral Uses</div>
								<div class="font-medium">{selectedBooking.user.referral_code_uses}</div>
							</div>
						{/if}
					</div>
					{#if selectedBooking.user?.notes}
						<div class="mt-3 rounded-md border border-blue-200 bg-blue-50 p-3">
							<div class="mb-1 text-xs font-semibold text-blue-800">Customer Notes</div>
							<div class="text-sm text-blue-900">{selectedBooking.user.notes}</div>
						</div>
					{/if}
				</div>

				<!-- Financial Summary -->
				<div class="rounded-lg border border-gray-200 bg-gray-50 p-4">
					<h3 class="mb-3 text-sm font-semibold tracking-wide text-gray-600 uppercase">
						Financial Summary
					</h3>
					<div class="space-y-2">
						{#if ['confirmed', 'in_progress', 'completed'].includes(selectedBooking.status) && selectedBooking.deposit_required}
							<!-- Deposit Info -->
							<div class="flex items-center justify-between border-b border-gray-200 pb-2">
								<span class="text-sm text-gray-600">Deposit Required</span>
								<div class="text-right">
									<div class="font-semibold">
										£{selectedBooking.deposit_amount?.toFixed(2) || '0.00'}
									</div>
									<div class="text-xs">
										<span
											class={selectedBooking.deposit_paid ? 'text-green-600' : 'text-orange-600'}
										>
											{selectedBooking.deposit_paid ? 'Paid' : 'Outstanding'}
										</span>
										{#if !selectedBooking.deposit_paid && selectedBooking.deposit_deadline}
											<span class="text-gray-500">
												• Due: {formatDateTime(selectedBooking.deposit_deadline)}
											</span>
										{/if}
									</div>
								</div>
							</div>
						{/if}

						<div class="flex items-center justify-between">
							<span class="text-sm text-gray-600">Subtotal (Services)</span>
							<span class="font-semibold">£{selectedBooking.total_amount.toFixed(2)}</span>
						</div>

						{#if selectedBooking.discounts && selectedBooking.discounts.length > 0}
							<div
								class="my-2 space-y-1 rounded-md border-y border-fuchsia-100 bg-fuchsia-50/20 px-2 py-2"
							>
								{#each selectedBooking.discounts as d (d.id)}
									<div class="flex items-center justify-between text-xs text-fuchsia-800">
										<span class="flex items-center gap-1.5">
											<span class="h-1.5 w-1.5 rounded-full bg-fuchsia-400"></span>
											{#if d.discount_source === 'loyalty'}
												Loyalty Stamp Card (10% Off)
											{:else if d.discount_source === 'referral'}
												Referral Discount ({d.discount_percent}% Off)
											{:else if d.campaign_name}
												{d.campaign_name} ({d.discount_percent}% Off)
											{:else}
												Promo Campaign ({d.discount_percent}% Off)
											{/if}
										</span>
										<span class="font-medium">-£{d.discount_amount.toFixed(2)}</span>
									</div>
								{/each}
							</div>
							<div class="flex items-center justify-between font-medium text-gray-900">
								<span class="text-sm">Net Total</span>
								<span
									>£{(
										selectedBooking.total_amount -
										selectedBooking.discounts.reduce((sum, d) => sum + d.discount_amount, 0)
									).toFixed(2)}</span
								>
							</div>
						{/if}

						<div class="flex items-center justify-between">
							<span class="text-sm text-gray-600">Amount Paid (Card/Cash)</span>
							<span class="font-semibold text-green-700">
								£{(selectedBooking.payments ?? [])
									.filter((p) => p.payment_method !== 'discount' && p.status === 'completed')
									.reduce((sum, p) => sum + p.amount, 0)
									.toFixed(2)}
							</span>
						</div>

						{#if totalRefunds > 0}
							<div class="flex items-center justify-between">
								<span class="text-sm text-red-600">Refunds</span>
								<span class="font-semibold text-red-600">-£{totalRefunds.toFixed(2)}</span>
							</div>
						{/if}

						<div class="flex items-center justify-between border-t border-gray-300 pt-2">
							<span class="font-medium text-gray-900">Balance Due</span>
							<span
								class="text-lg font-bold {balanceDue > 0.01 ? 'text-red-600' : 'text-green-600'}"
							>
								£{balanceDue.toFixed(2)}
							</span>
						</div>
					</div>
				</div>

				<!-- Payments -->
				{#if (selectedBooking.payments && selectedBooking.payments.length > 0) || (selectedBooking.refunds && selectedBooking.refunds.length > 0)}
					<div class="rounded-lg border border-gray-200 bg-gray-50 p-4">
						<h3 class="mb-3 text-sm font-semibold tracking-wide text-gray-600 uppercase">
							Payment History
						</h3>
						<div class="space-y-3">
							{#each selectedBooking.payments as payment, index (index)}
								<div class="rounded-md border border-gray-300 bg-white p-3">
									<div class="flex items-start justify-between">
										<div class="flex-1">
											<div class="flex items-center gap-2">
												<span class="font-medium text-gray-900">
													{getPaymentName(
														payment,
														index,
														selectedBooking.payments,
														selectedBooking.discounts
													)}
												</span>
												<span
													class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium
											{payment.status === 'completed'
														? 'bg-green-100 text-green-800'
														: payment.status === 'pending'
															? 'bg-yellow-100 text-yellow-800'
															: payment.status === 'failed'
																? 'bg-red-100 text-red-800'
																: 'bg-gray-100 text-gray-800'}"
												>
													{payment.status}
												</span>
											</div>
											<div class="mt-1 text-xs text-gray-500">
												{#if payment.payment_method === 'discount'}
													Applied automatically on completion
												{:else}
													{payment.payment_type.charAt(0).toUpperCase() +
														payment.payment_type.slice(1)} payment
													{#if payment.card_last4}
														, Card ending in {payment.card_last4}
													{/if}
												{/if}
											</div>
											{#if payment.vendor_code || payment.invoice_number}
												<div class="mt-1 text-xs text-gray-500">
													{#if payment.vendor_code}Vendor: {payment.vendor_code}{/if}
													{#if payment.vendor_code && payment.invoice_number}
														•
													{/if}
													{#if payment.invoice_number}Invoice: #{payment.invoice_number}{/if}
												</div>
											{/if}
											{#if payment.is_vat_applicable}
												<div class="mt-2 text-xs text-gray-600">
													<div>Net: £{payment.net_amount?.toFixed(2) || '0.00'}</div>
													<div>
														VAT ({payment.vat_rate || 0}%): £{payment.vat_amount?.toFixed(2) ||
															'0.00'}
													</div>
												</div>
											{/if}
											<div class="mt-1 text-xs text-gray-400">
												{formatDateTime(payment.created_at)}
											</div>
										</div>
										<div class="text-right font-semibold">
											{payment.payment_method === 'discount' ? '-' : ''}£{payment.amount.toFixed(2)}
										</div>
									</div>
								</div>
							{/each}

							{#each selectedBooking.refunds ?? [] as refund (refund.id)}
								<div class="rounded-md border border-red-200 bg-red-50 p-3">
									<div class="flex items-start justify-between">
										<div class="flex-1">
											<div class="flex items-center gap-2">
												<span class="font-medium text-red-700">Refund</span>
												<span
													class="inline-flex items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-800"
												>
													{refund.status}
												</span>
											</div>
											<div class="mt-1 text-xs text-red-600">
												{refund.reason || 'Refund processed'}
											</div>
											<div class="mt-1 text-xs text-gray-400">
												{formatDateTime(refund.created_at)}
											</div>
										</div>
										<div class="text-right font-semibold text-red-600">
											-£{refund.amount.toFixed(2)}
										</div>
									</div>
								</div>
							{/each}
						</div>
					</div>
				{/if}
			</div>
		{/if}

		<Modal.Footer class="flex items-center justify-end gap-2">
			{#if selectedBooking && !['completed', 'client_cancelled', 'we_cancelled', 'no_show', 'deposit_lapsed'].includes(selectedBooking.status)}
				<Button variant="destructive" size="sm" onclick={() => (showCancelModal = true)}>
					Cancel Booking
				</Button>
				<Button variant="outline" onclick={() => (showRescheduleModal = true)}>
					<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="M21.5 2v6h-6M2.5 22v-6h6M2 11.5a10 10 0 0 1 18.8-4.3M22 12.5a10 10 0 0 1-18.8 4.2"
						/>
					</svg>
					Reschedule
				</Button>
			{/if}
			<Button onclick={() => (open = false)}>Close</Button>
		</Modal.Footer>
	</Modal.Content>
</Modal.Root>

<!-- Approval Sub-Modal -->
{#if selectedBooking && showApprovalModal}
	<ApprovalModal
		bind:open={showApprovalModal}
		booking={selectedBooking}
		onApproved={() => {
			showApprovalModal = false;
			fetchBookingDetails();
		}}
	/>
{/if}

<!-- Reschedule Sub-Modal -->
{#if selectedBooking && showRescheduleModal}
	<RescheduleModal
		bind:open={showRescheduleModal}
		booking={selectedBooking}
		onSaved={() => {
			showRescheduleModal = false;
			fetchBookingDetails();
			onReschedule?.();
		}}
	/>
{/if}

{#if selectedBooking && showCancelModal}
	<Modal.Root bind:open={showCancelModal}>
		<Modal.Content class="!z-[80] max-w-[calc(100%-2rem)] sm:max-w-md">
			<Modal.Header>
				<Modal.Title>Cancel Booking</Modal.Title>
				<Modal.Description>
					{@const apptHours = Math.round(hoursUntilAppt)}
					{#if totalPaid > 0}
						<p>
							This booking has payments totalling <span class="font-semibold"
								>£{totalPaid.toFixed(2)}</span
							>.
						</p>
					{:else}
						<p>Are you sure you want to cancel this booking?</p>
					{/if}

					{#if totalPaid > 0}
						<div
							class="mt-3 rounded-md border p-3 text-sm {apptHours < 24
								? 'border-red-200 bg-red-50 text-red-800'
								: 'border-amber-200 bg-amber-50 text-amber-800'}"
						>
							<p class="font-medium">
								{apptHours > POLICY.FULL_REFUND_THRESHOLD_HOURS
									? `Full Refund — Over ${POLICY.FULL_REFUND_THRESHOLD_HOURS}h notice`
									: apptHours >= POLICY.PARTIAL_REFUND_THRESHOLD_HOURS
										? `Partial Refund — ${apptHours}h notice`
										: `No Refund — Under ${POLICY.PARTIAL_REFUND_THRESHOLD_HOURS}h notice`}
							</p>
							<p class="mt-1">
								{apptHours > POLICY.FULL_REFUND_THRESHOLD_HOURS
									? `You've given over ${POLICY.FULL_REFUND_THRESHOLD_HOURS} hours' notice. £${totalPaid.toFixed(2)} will be refunded in full.`
									: apptHours >= POLICY.PARTIAL_REFUND_THRESHOLD_HOURS
										? `You've paid £${totalPaid.toFixed(2)}. Up to ${POLICY.PROTECTED_DEPOSIT_MAX_PCT * 100}% of the total (£${(selectedBooking.total_amount * POLICY.PROTECTED_DEPOSIT_MAX_PCT).toFixed(2)}) counts as protected deposit. £${protectedDeposit.toFixed(2)} will be retained and £${estimatedRefund.toFixed(2)} will be refunded.`
										: `Under ${POLICY.PARTIAL_REFUND_THRESHOLD_HOURS}h notice. The full £${totalPaid.toFixed(2)} is retained to cover the lost slot.`}
							</p>
							<details class="mt-1 text-xs text-gray-500">
								<summary class="cursor-pointer hover:text-gray-700">What this means</summary>
								<p class="mt-1">
									{apptHours > 72
										? "Over 72 hours' notice means no deposit protection applies — a full refund is given regardless."
										: apptHours >= 24
											? "Between 24–72 hours' notice, up to 50% of the total (" +
												'£' +
												(selectedBooking.total_amount * 0.5).toFixed(2) +
												') is treated as a protected deposit to cover the lost slot. The remaining balance above that is refunded.'
											: "Under 24 hours' notice, the full amount paid (" +
												'£' +
												totalPaid.toFixed(2) +
												') is retained. This also counts as a no-show toward deposit obligations.'}
								</p>
							</details>
							<label class="mt-2 flex cursor-pointer items-center gap-2">
								<Checkbox bind:checked={forgiveFeesCancel} />
								<span class="text-xs"
									>Forgive fees — refund the <strong>full</strong> amount paid</span
								>
							</label>
							<details class="ml-6 text-xs text-gray-500">
								<summary class="cursor-pointer hover:text-gray-700"
									>What happens with forgiveness</summary
								>
								<p class="mt-1">
									"We've applied a full refund to this booking as a goodwill gesture. No deposit
									protection will be applied."
								</p>
							</details>

							<p class="mt-3 font-medium">No-Show Record</p>
							<p class="mt-1">This cancellation counts as a no-show toward deposit obligations.</p>
							<details class="mt-1 text-xs text-gray-500">
								<summary class="cursor-pointer hover:text-gray-700">What this means</summary>
								<p class="mt-1">
									"This cancellation will count as a no-show toward your booking history. Two
									no-shows within 6 months would require a deposit on future bookings to secure your
									appointment."
								</p>
							</details>
							<label class="mt-2 flex cursor-pointer items-center gap-2">
								<Checkbox bind:checked={forgiveNoShowCancel} />
								<span class="text-xs"
									>Forgive no-show — this cancellation will <strong>not</strong> count toward deposit
									obligations</span
								>
							</label>
							<details class="ml-6 text-xs text-gray-500">
								<summary class="cursor-pointer hover:text-gray-700"
									>What happens with forgiveness</summary
								>
								<p class="mt-1">
									"We've waived the no-show record for this cancellation so your deposit obligations
									remain unaffected."
								</p>
							</details>
						</div>
					{:else if apptHours < 24}
						<div class="mt-2 rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-800">
							<p class="font-semibold text-red-900">
								No-Show Warning — {apptHours}h before appointment
							</p>
							<p class="mt-1">
								This booking has no payments but is under 24 hours' notice. Cancelling counts as a
								no-show toward deposit obligations.
							</p>
							<details class="mt-1 text-xs text-gray-500">
								<summary class="cursor-pointer hover:text-gray-700">What this means</summary>
								<p class="mt-1">
									"This cancellation will count as a no-show toward your booking history. Two
									no-shows within 6 months would require a deposit on future bookings to secure your
									appointment."
								</p>
							</details>
							<label class="mt-2 flex cursor-pointer items-center gap-2">
								<Checkbox bind:checked={forgiveNoShowCancel} />
								<span class="text-xs"
									>Forgive no-show — this cancellation will <strong>not</strong> count toward deposit
									obligations</span
								>
							</label>
							<details class="mt-1 ml-6 text-xs text-gray-500">
								<summary class="cursor-pointer hover:text-gray-700"
									>What happens with forgiveness</summary
								>
								<p class="mt-1">
									"We've waived the no-show record for this cancellation. Your deposit obligations
									will not be affected."
								</p>
							</details>
						</div>
					{:else}
						<div
							class="mt-2 rounded-md border border-blue-200 bg-blue-50 p-3 text-sm text-blue-800"
						>
							<p class="font-medium">Clean Cancellation</p>
							<p class="mt-1">This booking has no payments. The booking will be removed cleanly.</p>
						</div>
					{/if}
					<p class="mt-3 text-xs text-gray-500">
						<PolicyPopover>
							{#snippet trigger()}
								<span class="underline">View full cancellation policy →</span>
							{/snippet}
						</PolicyPopover>
					</p>
				</Modal.Description>
			</Modal.Header>
			<Modal.Footer class="flex gap-2">
				<Button variant="outline" onclick={() => (showCancelModal = false)} disabled={cancelling}>
					Keep Booking
				</Button>
				<Button variant="destructive" onclick={handleAdminCancel} disabled={cancelling}>
					{cancelling ? 'Cancelling...' : 'Yes, Cancel'}
				</Button>
			</Modal.Footer>
		</Modal.Content>
	</Modal.Root>
{/if}
