<script lang="ts">
	import { apiFetch } from '$lib/utils/api';
	import { SvelteDate } from 'svelte/reactivity';
	import { toast } from 'svelte-sonner';
	import * as Card from '$lib/components/ui/card';
	import { Button } from '$lib/components/ui/button';
	import { Badge } from '$lib/components/ui/badge';
	import { Skeleton } from '$lib/components/ui/skeleton';
	import ApprovalModal from '$lib/components/admin/ApprovalModal.svelte';
	import EditRequestModal from '$lib/components/admin/EditRequestModal.svelte';
	import { formatUserName } from '$lib/utils/nameDisplay';

	interface Props {
		openBookingModal?: (bookingId: string) => void;
		hasItems?: boolean;
	}

	let { openBookingModal, hasItems = $bindable(false) }: Props = $props();

	// Edit request types
	interface ServiceItem {
		id: string;
		name: string;
		price: number;
		duration_minutes: number;
	}

	interface EditRequest {
		id: string;
		booking_id: string;
		requested_by: string;
		requested_at: string;
		notes: string | null;
		original: {
			start_time: string;
			end_time: string;
			services: ServiceItem[];
			notes: string;
		};
		proposed: {
			start_time: string | null;
			end_time: string | null;
			services: ServiceItem[];
			notes: string | null;
		};
		user: {
			id: string;
			full_name: string;
			email: string;
			phone: string;
			previous_first_name?: string | null;
			previous_last_name?: string | null;
		};
	}

	// Match the backend structure
	type PendingApproval = {
		id: string;
		start_time: string;
		user_id: string;
		user_name: string; // This is a string, not an object
		previous_first_name?: string | null;
		previous_last_name?: string | null;
		services: string[]; // Array of service names
		duration_minutes: number;
		created_at: string;
	};

	type PendingBooking = {
		id: string;
		start_time: string;
		notes?: string;
		user?: {
			id: string;
			full_name: string;
			email?: string;
			phone?: string;
		};
		services: Array<{
			service_id: string;
			service_name?: string;
			price?: number;
			duration_minutes?: number;
		}>;
		duration_minutes: number;
		created_at: string;
	};

	let pendingApprovals = $state<PendingApproval[]>([]);
	const visibleApprovals = $derived(pendingApprovals.slice(0, 3));
	let loading = $state(true);
	let showApprovalModal = $state(false);
	let selectedBooking = $state<PendingBooking | null>(null);

	let pendingEditRequests = $state<EditRequest[]>([]);
	const visibleEditRequests = $derived(pendingEditRequests.slice(0, 3));
	let showEditRequestModal = $state(false);
	let selectedEditRequest = $state<EditRequest | null>(null);

	const _hasItems = $derived(pendingApprovals.length > 0 || pendingEditRequests.length > 0);
	$effect(() => {
		hasItems = _hasItems;
	});

	// Helper function to format date nicely
	function formatDateTime(dateTimeString: string): string {
		const date = new SvelteDate(dateTimeString);
		const dateStr = date.toLocaleDateString('en-US', {
			weekday: 'long',
			day: 'numeric',
			month: 'short'
		});
		const timeStr = date.toLocaleTimeString('en-US', {
			hour: 'numeric',
			minute: '2-digit',
			hour12: true
		});
		return `${dateStr} at ${timeStr}`;
	}

	function formatRelativeTime(iso: string): string {
		const d = new SvelteDate(iso);
		const now = new SvelteDate();
		const diffMs = now.getTime() - d.getTime();
		const diffMin = Math.floor(diffMs / 60000);

		if (diffMin < 1) return 'Just now';
		if (diffMin < 60) return `${diffMin}m ago`;
		const diffHr = Math.floor(diffMin / 60);
		if (diffHr < 24) return `${diffHr}h ago`;
		const diffDay = Math.floor(diffHr / 24);
		return `${diffDay}d ago`;
	}

	function getEditRequestSummary(er: EditRequest): string {
		const timeChanged = er.proposed.start_time && er.proposed.start_time !== er.original.start_time;
		const servicesChanged = areEditServicesChanged(er);

		if (timeChanged) {
			const d = new SvelteDate(er.proposed.start_time!);
			const dateStr = d.toLocaleDateString('en-US', {
				weekday: 'long',
				day: 'numeric',
				month: 'short'
			});
			const timeStr = d.toLocaleTimeString('en-US', {
				hour: 'numeric',
				minute: '2-digit',
				hour12: true
			});
			return `Requested change to ${dateStr} at ${timeStr}`;
		}
		if (servicesChanged) {
			return 'Requested change to services';
		}
		return 'Requested change';
	}

	function areEditServicesChanged(er: EditRequest): boolean {
		const origIds = new Set(er.original.services.map((s) => s.id));
		const propIds = new Set(er.proposed.services.map((s) => s.id));
		if (origIds.size !== propIds.size) return true;
		for (const id of origIds) {
			if (!propIds.has(id)) return true;
		}
		return false;
	}

	function getServiceSummary(er: EditRequest): string {
		const names = er.proposed.services.map((s) => s.name).filter(Boolean);
		return names.join(', ') || 'No services';
	}

	let prevApprovalsJson = $state('');
	let prevEditRequestsJson = $state('');
	let initialized = $state(false);

	async function fetchPendingApprovals() {
		if (!initialized) loading = true;
		try {
			const response = await apiFetch('/api/admin/today/pending-approvals', {
				headers: { 'Content-Type': 'application/json' }
			});

			if (response.ok) {
				const data = await response.json();
				const newApprovals = (data.approvals || []).sort(
					(a: PendingApproval, b: PendingApproval) =>
						new SvelteDate(a.created_at).getTime() - new SvelteDate(b.created_at).getTime()
				);
				const newJson = JSON.stringify(newApprovals);
				if (newJson !== prevApprovalsJson) {
					pendingApprovals = newApprovals;
					prevApprovalsJson = newJson;
				}
			} else {
				toast.error('Failed to load pending approvals');
			}
		} catch (err) {
			console.error('Error fetching pending approvals:', err);
			toast.error('Network error loading pending approvals');
		} finally {
			if (!initialized) {
				loading = false;
				initialized = true;
			}
		}
	}

	async function fetchEditRequests() {
		try {
			const response = await apiFetch('/api/admin/bookings/edit-requests', {
				headers: { 'Content-Type': 'application/json' }
			});

			if (response.ok) {
				const data = await response.json();
				const newEditRequests = (data.edit_requests || []).sort(
					(a: EditRequest, b: EditRequest) =>
						new SvelteDate(a.requested_at).getTime() - new SvelteDate(b.requested_at).getTime()
				);
				const newJson = JSON.stringify(newEditRequests);
				if (newJson !== prevEditRequestsJson) {
					pendingEditRequests = newEditRequests;
					prevEditRequestsJson = newJson;
				}
			}
		} catch (err) {
			console.error('Error fetching edit requests:', err);
		}
	}

	async function openApprovalModal(bookingId: string) {
		try {
			const response = await apiFetch(`/api/admin/bookings/${bookingId}`);
			if (!response.ok) throw new Error(await response.text());

			const data = await response.json();
			selectedBooking = data; // now has full services with price/duration
			showApprovalModal = true;
		} catch (err) {
			console.error('Failed to load booking details:', err);
			toast.error('Failed to load booking details');
		}
	}

	function openReviewModal(editRequest: EditRequest) {
		selectedEditRequest = editRequest;
		showEditRequestModal = true;
	}

	$effect(() => {
		fetchPendingApprovals();
		fetchEditRequests();

		const intervalId = setInterval(() => {
			fetchPendingApprovals();
			fetchEditRequests();
		}, 60_000);

		function handleBookingApproved() {
			fetchPendingApprovals();
			fetchEditRequests();
		}
		window.addEventListener('bookingApproved', handleBookingApproved);

		return () => {
			clearInterval(intervalId);
			window.removeEventListener('bookingApproved', handleBookingApproved);
		};
	});
</script>

<Card.Root>
	<Card.Header>
		<div class="flex items-start justify-between">
			<div>
				<Card.Title class="flex items-center gap-2">
					<svg
						xmlns="http://www.w3.org/2000/svg"
						class="h-5 w-5 text-amber-600"
						viewBox="0 0 20 20"
						fill="currentColor"
					>
						<path
							fill-rule="evenodd"
							d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z"
							clip-rule="evenodd"
						/>
					</svg>
					Pending Approvals
				</Card.Title>
				<Card.Description>
					{#if pendingApprovals.length > 0 && pendingEditRequests.length > 0}
						New bookings and customer-requested changes awaiting review
					{:else if pendingApprovals.length > 0}
						New bookings awaiting confirmation
					{:else if pendingEditRequests.length > 0}
						Customer-requested booking changes awaiting review
					{:else}
						New bookings awaiting confirmation
					{/if}
				</Card.Description>
			</div>
			{#if !loading}
				<Badge class="bg-amber-100 text-amber-800 hover:bg-amber-100">
					{pendingApprovals.length + pendingEditRequests.length}
				</Badge>
			{/if}
		</div>
	</Card.Header>
	<Card.Content>
		{#if loading}
			<div class="space-y-3">
				{#each Array(3) as _, i (i)}
					<div class="rounded-lg border p-3">
						<div class="flex items-start justify-between">
							<div class="flex-1 space-y-2">
								<Skeleton class="h-4 w-32" />
								<Skeleton class="h-3 w-48" />
								<Skeleton class="h-3 w-24" />
							</div>
							<Skeleton class="h-8 w-20" />
						</div>
					</div>
				{/each}
			</div>
		{:else if pendingApprovals.length === 0 && pendingEditRequests.length === 0}
			<div class="py-8 text-center">
				<svg
					xmlns="http://www.w3.org/2000/svg"
					class="mx-auto mb-3 h-12 w-12 text-gray-300"
					fill="none"
					viewBox="0 0 24 24"
					stroke="currentColor"
					stroke-width="1.5"
				>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
					/>
				</svg>
				<p class="text-sm font-medium text-gray-600">All caught up!</p>
				<p class="text-xs text-gray-500">Nothing pending to review</p>
			</div>
		{:else}
			<div class="space-y-3">
				{#each visibleApprovals as approval (approval.id)}
					<div
						class="rounded-lg border border-amber-200 bg-amber-50/30 p-3 transition-all hover:shadow-md"
					>
						<div class="flex items-start justify-between gap-3">
							<div class="flex-1">
								<div class="font-medium">
									{formatUserName(
										approval.user_name || 'Guest',
										approval.previous_first_name,
										approval.previous_last_name
									)}
								</div>
								<div class="mt-1 text-sm text-gray-600">
									{approval.services.join(', ')}
								</div>
								<div class="mt-1 text-xs text-gray-500">
									<div class="flex flex-col gap-1 sm:flex-row sm:items-center sm:gap-2">
										<span>
											{formatDateTime(approval.start_time)}
										</span>
										<span class="hidden sm:inline">•</span>
										<span>
											{approval.duration_minutes} mins
										</span>
									</div>
								</div>
							</div>
							<div class="flex flex-col gap-2">
								<Button
									size="sm"
									onclick={() => openApprovalModal(approval.id)}
									class="bg-emerald-600 hover:bg-emerald-700"
								>
									Approve
								</Button>
								{#if openBookingModal}
									<Button size="sm" variant="outline" onclick={() => openBookingModal(approval.id)}>
										Details
									</Button>
								{/if}
							</div>
						</div>
					</div>
				{/each}

				{#if pendingApprovals.length > 0 && pendingEditRequests.length > 0}
					<div class="border-t border-gray-200 pt-3"></div>
				{/if}

				{#each visibleEditRequests as er (er.id)}
					<div
						class="rounded-lg border border-amber-200 bg-amber-50/30 p-3 transition-all hover:shadow-md"
					>
						<div class="flex items-start justify-between gap-3">
							<div class="flex-1">
								<div class="flex items-center gap-2">
									<span class="font-medium"
										>{formatUserName(
											er.user?.full_name || 'Unknown',
											er.user?.previous_first_name,
											er.user?.previous_last_name
										)}</span
									>
									<span class="text-xs font-medium text-amber-600">Edit/Reschedule</span>
								</div>
								<div class="mt-1 text-sm text-gray-600">
									{getEditRequestSummary(er)}
								</div>
								<div class="mt-1 text-xs text-gray-500">
									{getServiceSummary(er)}
								</div>
								<div class="mt-1 text-xs text-gray-400">
									Requested {formatRelativeTime(er.requested_at)}
								</div>
							</div>
							<div class="flex flex-col gap-2">
								<Button
									size="sm"
									onclick={() => openReviewModal(er)}
									class="bg-amber-600 hover:bg-amber-700"
								>
									Review
								</Button>
							</div>
						</div>
					</div>
				{/each}
			</div>
		{/if}
	</Card.Content>
</Card.Root>

<!-- Approval Modal -->
{#if selectedBooking && showApprovalModal}
	<ApprovalModal
		bind:open={showApprovalModal}
		booking={selectedBooking}
		onApproved={() => {
			showApprovalModal = false;
			fetchPendingApprovals();
			window.dispatchEvent(new CustomEvent('bookingApproved'));
		}}
	/>
{/if}

<!-- Edit Request Modal -->
{#if selectedEditRequest && showEditRequestModal}
	<EditRequestModal
		bind:open={showEditRequestModal}
		editRequest={selectedEditRequest}
		onApproved={() => {
			showEditRequestModal = false;
			selectedEditRequest = null;
			fetchPendingApprovals();
			fetchEditRequests();
		}}
		onDenied={() => {
			showEditRequestModal = false;
			selectedEditRequest = null;
			fetchPendingApprovals();
			fetchEditRequests();
		}}
	/>
{/if}
