<script lang="ts">
	import { toast } from 'svelte-sonner';
	import { apiFetch } from '$lib/utils/api';

	// shadcn-svelte components
	import { Button } from '$lib/components/ui/button';
	import * as Card from '$lib/components/ui/card';
	import { Input } from '$lib/components/ui/input';
	import * as Modal from '$lib/components/ui/dialog';
	import { Skeleton } from '$lib/components/ui/skeleton';
	import { SvelteMap } from 'svelte/reactivity';

	// =============== Types ===============
	type Service = {
		id: string;
		name: string;
		description: string;
		price: number;
		duration_minutes: number;
		is_active: boolean;
		patch_test_duration_hours: number;
		minimum_age_required: number;
		created_at: string;
		created_by?: string;
	};

	interface Props {
		services?: Service[];
		onRefresh?: () => Promise<void>;
	}

	let { services: servicesProp, onRefresh }: Props = $props();

	const durationOptions = Array.from({ length: 32 }, (_, i) => (i + 1) * 15);

	let services = $state<Service[]>([]);
	let newService = $state<
		Omit<Service, 'id' | 'created_at' | 'created_by' | 'patch_test_duration_hours'>
	>({
		name: '',
		description: '',
		price: 0,
		duration_minutes: 0,
		is_active: true,
		minimum_age_required: 0
	});
	let servicesLoading = $state(true);
	const servicesUpdating = $state<Record<string, boolean>>({});
	let showServiceModal = $state(false);
	let creatingService = $state(false);
	let serviceErrors = $state<Record<string, string>>({});

	function validatePrice(price: number | string): string {
		if (price === null || price === undefined || price === '') {
			return 'Price is required';
		}
		const numPrice = parseFloat(typeof price === 'number' ? price.toString() : price);
		if (isNaN(numPrice)) {
			return 'Price must be a valid number';
		}

		if (numPrice <= 0) {
			return 'Price must be greater than 0';
		}

		const decimalRegex = /^\d+(\.\d{1,2})?$/;
		if (!decimalRegex.test(price.toString())) {
			return 'Price can have up to 2 decimal places';
		}

		return '';
	}

	function validateDuration(value: number | string, field: string): string {
		if (value === null || value === undefined || value === '') {
			return 'Field cannot be empty';
		}
		const num = Number(value);
		if (isNaN(num)) {
			return 'Must be a valid number';
		}

		if (!Number.isInteger(num)) {
			return 'Must be a whole number';
		}

		if (field === 'duration_minutes' && num <= 0) {
			return 'Duration must be greater than 0';
		}

		if (field === 'minimum_age_required' && (num < 0 || num > 100)) {
			return 'Must be between 0 and 100';
		}

		return '';
	}

	function validateName(name: string): string {
		if (!name.trim()) {
			return 'Service name is required';
		}
		return '';
	}

	function updateAllErrors() {
		serviceErrors = {
			name: validateName(newService.name),
			price: validatePrice(newService.price),
			duration_minutes: validateDuration(newService.duration_minutes, 'duration_minutes'),
			minimum_age_required: validateDuration(
				newService.minimum_age_required,
				'minimum_age_required'
			)
		};
	}

	function validateNameField() {
		serviceErrors.name = validateName(newService.name);
	}

	function validatePriceField() {
		serviceErrors.price = validatePrice(newService.price);
	}

	function validateDurationField() {
		serviceErrors.duration_minutes = validateDuration(
			newService.duration_minutes,
			'duration_minutes'
		);
	}

	function validateMinimumAgeField() {
		serviceErrors.minimum_age_required = validateDuration(
			newService.minimum_age_required,
			'minimum_age_required'
		);
	}

	const isFormValid = $derived(
		newService.name !== '' &&
			!serviceErrors.name &&
			!serviceErrors.price &&
			!serviceErrors.duration_minutes &&
			!serviceErrors.minimum_age_required
	);

	// =============== API Functions ===============
	async function fetchServices() {
		// If the parent provides services via prop, delegate refresh to parent
		if (servicesProp && onRefresh) {
			await onRefresh();
			return;
		}

		servicesLoading = true;
		try {
			const response = await apiFetch('/api/admin/services', {
				headers: {
					'Content-Type': 'application/json'
				}
			});

			if (response.ok) {
				const data = await response.json();
				const uniqueServices = new SvelteMap<string, Service>();
				data.forEach((s: Service) => {
					if (s.id) uniqueServices.set(s.id, s);
				});
				services = Array.from(uniqueServices.values());
			} 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;
		}
	}

	async function toggleService(serviceId: string) {
		servicesUpdating[serviceId] = true;
		try {
			const response = await apiFetch(`/api/admin/services/${serviceId}/toggle`, {
				method: 'PUT'
			});

			if (response.ok) {
				toast.success('Service status updated');
				await fetchServices();
			} else {
				const errorText = await response.text();
				toast.error(`Failed to update service: ${errorText}`);
			}
		} catch (err) {
			console.error('Error toggling service:', err);
			toast.error('Network error updating service');
		} finally {
			servicesUpdating[serviceId] = false;
		}
	}

	async function deleteService(serviceId: string) {
		if (!confirm('Are you sure you want to delete this service? This action cannot be undone.')) {
			return;
		}

		servicesUpdating[serviceId] = true;

		try {
			const response = await apiFetch(`/api/admin/services/${serviceId}`, {
				method: 'DELETE'
			});

			if (response.ok) {
				toast.success('Service deleted successfully');
				await fetchServices();
			} else {
				const errorText = await response.text();
				toast.error(`Failed to delete service: ${errorText}`);
			}
		} catch (err) {
			console.error('Error deleting service:', err);
			toast.error('Network error deleting service');
		} finally {
			servicesUpdating[serviceId] = false;
		}
	}

	async function createService() {
		updateAllErrors();

		const hasErrors = Object.values(serviceErrors).some((error) => error !== '');
		if (hasErrors) {
			toast.error('Please fix the validation errors before submitting');
			return;
		}

		if (!isFormValid) {
			toast.error('Form validation failed');
			return;
		}

		creatingService = true;
		const loadingToast = toast.loading('Creating service...');

		try {
			const payload = {
				name: newService.name.trim(),
				description: newService.description.trim() || undefined,
				price: Number(newService.price),
				duration_minutes: Number(newService.duration_minutes),
				minimum_age_required: Number(newService.minimum_age_required)
			};

			const response = await apiFetch('/api/admin/services', {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify(payload)
			});

			if (response.ok) {
				await response.json();
				toast.success('Service created successfully!', { id: loadingToast });

				resetServiceForm();
				showServiceModal = false;

				await fetchServices();
			} else if (response.status === 409) {
				toast.error('A service with this name already exists', { id: loadingToast });
			} else if (response.status === 400) {
				const errorText = await response.text();
				toast.error(`Validation error: ${errorText}`, { id: loadingToast });
			} else {
				const errorText = await response.text();
				toast.error(`Failed to create service: ${errorText}`, { id: loadingToast });
			}
		} catch (err) {
			console.error('Error creating service:', err);
			toast.error('Network error creating service', { id: loadingToast });
		} finally {
			creatingService = false;
		}
	}

	function resetServiceForm() {
		newService = {
			name: '',
			description: '',
			price: 0,
			duration_minutes: 60,
			is_active: true,
			minimum_age_required: 0
		};
		serviceErrors = {
			name: '',
			price: '',
			duration_minutes: '',
			minimum_age_required: ''
		};
	}

	function openServiceModal() {
		resetServiceForm();
		showServiceModal = true;
	}

	// =============== Lifecycle ===============
	// Single effect: sync from prop when provided, self-fetch when not.
	// Combined into one effect to prevent the reactive loop where
	// fetchServices() → onRefresh() → parent updates → servicesProp changes → effect re-runs.
	$effect(() => {
		if (servicesProp !== undefined) {
			if (servicesProp.length > 0) {
				services = servicesProp;
			}
			servicesLoading = false;
		} else {
			fetchServices();
		}
	});
</script>

<Card.Root>
	<Card.Header>
		<div class="flex items-center justify-between">
			<div>
				<Card.Title>Services Management</Card.Title>
				<Card.Description>
					Manage your services - add, edit, toggle availability, or delete services.
				</Card.Description>
			</div>
			<Button onclick={openServiceModal}>
				<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"
				>
					<line x1="12" y1="5" x2="12" y2="19" />
					<line x1="5" y1="12" x2="19" y2="12" />
				</svg>
				Add Service
			</Button>
		</div>
	</Card.Header>

	<Card.Content class="space-y-4">
		<div class="hidden w-full overflow-x-auto md:block">
			<table class="w-full table-auto border-collapse text-sm">
				<thead>
					<tr class="border-b text-left text-xs text-gray-500">
						<th class="w-[20%] py-3 font-medium">Name</th>
						<th class="w-[30%] py-3 font-medium">Description</th>
						<th class="w-[10%] py-3 text-right font-medium">Price</th>
						<th class="w-[12%] py-3 text-right font-medium">Duration</th>
						<th class="w-[12%] py-3 text-center font-medium">Status</th>
						<th class="w-[16%] py-3 text-center font-medium">Actions</th>
					</tr>
				</thead>
				<tbody>
					{#if servicesLoading}
						{#each Array(3) as _, i (i)}
							<tr class="border-b">
								<td class="py-3"><Skeleton class="h-4 w-32" /></td>
								<td class="py-3"><Skeleton class="h-4 w-48" /></td>
								<td class="py-3 text-right"><Skeleton class="ml-auto h-4 w-16" /></td>
								<td class="py-3 text-right"><Skeleton class="ml-auto h-4 w-20" /></td>
								<td class="py-3 text-center"><Skeleton class="mx-auto h-4 w-16" /></td>
								<td class="py-3 text-center">
									<div class="flex justify-center gap-2">
										<Skeleton class="h-8 w-16" />
										<Skeleton class="h-8 w-16" />
									</div>
								</td>
							</tr>
						{/each}
					{:else}
						{#each services as service (service.id)}
							<tr class="border-b hover:bg-gray-50">
								<td class="py-3 font-medium">{service.name}</td>
								<td class="py-3 text-gray-600">
									{#if service.description}
										<div class="line-clamp-2" title={service.description}>
											{service.description}
										</div>
									{:else}
										<span class="text-gray-400">—</span>
									{/if}
								</td>
								<td class="py-3 text-right font-medium">£{service.price.toFixed(2)}</td>
								<td class="py-3 text-right">{service.duration_minutes} min</td>
								<td class="py-3 text-center">
									<span
										class="inline-flex items-center rounded-full px-2 py-1 text-xs font-medium {service.is_active
											? 'bg-emerald-100 text-emerald-800'
											: 'bg-red-100 text-red-800'}"
									>
										{service.is_active ? 'Active' : 'Inactive'}
									</span>
								</td>
								<td class="py-3">
									<div class="flex justify-center gap-2">
										<Button
											variant="outline"
											size="sm"
											onclick={() => toggleService(service.id)}
											disabled={servicesUpdating[service.id]}
										>
											{servicesUpdating[service.id]
												? '...'
												: service.is_active
													? 'Deactivate'
													: 'Activate'}
										</Button>
										<Button
											variant="destructive"
											size="sm"
											onclick={() => deleteService(service.id)}
											disabled={servicesUpdating[service.id]}
										>
											Delete
										</Button>
									</div>
								</td>
							</tr>
						{/each}
					{/if}
				</tbody>
			</table>
		</div>

		<div class="space-y-4 md:hidden">
			{#if servicesLoading}
				{#each Array(3) as _, i (i)}
					<div class="rounded-lg border p-4">
						<div class="space-y-3">
							<Skeleton class="h-5 w-32" />
							<Skeleton class="h-4 w-48" />
							<div class="flex justify-between">
								<Skeleton class="h-4 w-16" />
								<Skeleton class="h-4 w-20" />
							</div>
							<div class="flex gap-2">
								<Skeleton class="h-8 w-16" />
								<Skeleton class="h-8 w-16" />
							</div>
						</div>
					</div>
				{/each}
			{:else}
				{#each services as service (service.id)}
					<div class="rounded-lg border p-4 hover:bg-gray-50">
						<div class="space-y-3">
							<div class="flex items-start justify-between">
								<h3 class="font-medium">{service.name}</h3>
								<span
									class="inline-flex items-center rounded-full px-2 py-1 text-xs font-medium {service.is_active
										? 'bg-emerald-100 text-emerald-800'
										: 'bg-red-100 text-red-800'}"
								>
									{service.is_active ? 'Active' : 'Inactive'}
								</span>
							</div>

							{#if service.description}
								<p class="text-sm text-gray-600">{service.description}</p>
							{/if}

							<div class="flex justify-between text-sm">
								<div>
									<span class="font-medium">Price:</span> £{service.price.toFixed(2)}
								</div>
								<div>
									<span class="font-medium">Duration:</span>
									{service.duration_minutes} min
								</div>
							</div>

							<div class="flex gap-2 pt-2">
								<Button
									variant="outline"
									size="sm"
									onclick={() => toggleService(service.id)}
									disabled={servicesUpdating[service.id]}
									class="flex-1"
								>
									{servicesUpdating[service.id]
										? '...'
										: service.is_active
											? 'Deactivate'
											: 'Activate'}
								</Button>
								<Button
									variant="destructive"
									size="sm"
									onclick={() => deleteService(service.id)}
									disabled={servicesUpdating[service.id]}
									class="flex-1"
								>
									Delete
								</Button>
							</div>
						</div>
					</div>
				{/each}
			{/if}
		</div>

		{#if !servicesLoading && services.length === 0}
			<div class="py-8 text-center text-gray-500">
				No services found. Click "Add Service" to create your first service.
			</div>
		{/if}
	</Card.Content>
</Card.Root>

<Modal.Root bind:open={showServiceModal}>
	<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">Add New Service</Modal.Title>
			<Modal.Description>Create a new service that customers can book.</Modal.Description>
		</Modal.Header>

		<div class="space-y-4 px-4 pb-4">
			<div class="space-y-2">
				<label for="service-name" class="text-sm font-medium">Service Name *</label>
				<Input
					id="service-name"
					type="text"
					maxlength={100}
					placeholder="e.g., Haircut, Color, Blowdry"
					bind:value={newService.name}
					onblur={validateNameField}
					class="w-full {serviceErrors.name ? 'border-red-500' : ''}"
				/>
				{#if serviceErrors.name}
					<p class="text-sm text-red-600">{serviceErrors.name}</p>
				{/if}
			</div>

			<div class="space-y-2">
				<label for="service-description" class="text-sm font-medium">Description</label>
				<Input
					id="service-description"
					type="text"
					placeholder="Brief description of the service, will be shown to customers"
					bind:value={newService.description}
					class="w-full"
				/>
			</div>

			<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
				<div class="space-y-2">
					<label for="service-price" class="text-sm font-medium">Price (£) *</label>
					<div class="relative">
						<span class="absolute top-1/2 left-3 -translate-y-1/2 text-sm text-gray-500">£</span>
						<Input
							id="service-price"
							type="number"
							inputmode="decimal"
							step="0.01"
							min="0"
							placeholder="0.00"
							bind:value={newService.price}
							onblur={validatePriceField}
							class="w-full pl-8 {serviceErrors.price ? 'border-red-500' : ''}"
						/>
					</div>
					{#if serviceErrors.price}
						<p class="text-sm text-red-600">{serviceErrors.price}</p>
					{/if}
				</div>

				<div class="space-y-2">
					<label for="service-duration" class="text-sm font-medium">Duration *</label>
					<select
						id="service-duration"
						bind:value={newService.duration_minutes}
						onblur={validateDurationField}
						class="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-xs ring-offset-background transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 {serviceErrors.duration_minutes
							? 'border-red-500'
							: ''}"
					>
						<option value={0}>Select...</option>
						{#each durationOptions as mins (mins)}
							<option value={mins}
								>{mins} min{mins >= 60
									? ` (${Math.floor(mins / 60)}h${mins % 60 > 0 ? ` ${mins % 60}m` : ''})`
									: ''}</option
							>
						{/each}
					</select>
					{#if serviceErrors.duration_minutes}
						<p class="text-sm text-red-600">{serviceErrors.duration_minutes}</p>
					{/if}
				</div>
			</div>

			<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
				<div class="space-y-2">
					<label for="minimum-age" class="text-sm font-medium">Minimum Age</label>
					<Input
						id="minimum-age"
						type="number"
						inputmode="numeric"
						min="0"
						max="100"
						step="1"
						placeholder="0"
						bind:value={newService.minimum_age_required}
						onblur={validateMinimumAgeField}
						class="w-full {serviceErrors.minimum_age_required ? 'border-red-500' : ''}"
					/>
					{#if serviceErrors.minimum_age_required}
						<p class="text-sm text-red-600">{serviceErrors.minimum_age_required}</p>
					{/if}
					<p class="text-xs text-gray-500">0 for no age restriction</p>
				</div>
			</div>
		</div>

		<Modal.Footer class="flex items-center justify-end gap-2">
			<Button
				variant="outline"
				onclick={() => {
					showServiceModal = false;
					resetServiceForm();
				}}
				disabled={creatingService}
			>
				Cancel
			</Button>
			<Button onclick={createService} disabled={creatingService || !isFormValid}>
				{creatingService ? 'Creating...' : 'Create Service'}
			</Button>
		</Modal.Footer>
	</Modal.Content>
</Modal.Root>
