<script lang="ts">
	import { fade, scale } from 'svelte/transition';
	import type { Snippet } from 'svelte';

	interface Props {
		open: boolean;
		title: string;
		subtitle: string;
		itemName: string;
		itemNamePlural?: string;
		loading?: boolean;
		saving?: boolean;
		error?: string;
		selectedCount: number;
		hasItems: boolean;
		emptyMessage?: string;
		showTotal?: boolean;
		selectedTotal?: number;
		colorScheme?: 'primary' | 'secondary' | 'accent';
		onSave: () => void;
		onClose: () => void;
		selectAll?: () => void;
		selectNone?: () => void;
		children: Snippet;
	}

	let {
		open = $bindable(false),
		title,
		subtitle,
		itemName,
		itemNamePlural,
		loading = false,
		saving = false,
		error = '',
		selectedCount,
		hasItems,
		emptyMessage = 'No items available.',
		showTotal = false,
		selectedTotal = 0,
		colorScheme = 'primary',
		onSave,
		onClose,
		selectAll,
		selectNone,
		children
	}: Props = $props();

	let plural = $derived(itemNamePlural ?? `${itemName}s`);

	function formatCurrency(value: number): string {
		return new Intl.NumberFormat('en-US', {
			style: 'currency',
			currency: 'USD'
		}).format(value);
	}

	function handleClose() {
		open = false;
		onClose();
	}

	function handleBackdropClick(e: MouseEvent) {
		if (e.target === e.currentTarget) {
			handleClose();
		}
	}

	// Color scheme classes
	let colorClasses = $derived({
		selectAll:
			colorScheme === 'primary'
				? 'text-primary-600 dark:text-primary-400'
				: colorScheme === 'secondary'
					? 'text-secondary-600 dark:text-secondary-400'
					: 'text-accent-600 dark:text-accent-400',
		totalBg:
			colorScheme === 'primary'
				? 'bg-primary-500/10'
				: colorScheme === 'secondary'
					? 'bg-secondary-500/10'
					: 'bg-accent-500/10',
		totalText:
			colorScheme === 'primary'
				? 'text-primary-600 dark:text-primary-400'
				: colorScheme === 'secondary'
					? 'text-secondary-600 dark:text-secondary-400'
					: 'text-accent-600 dark:text-accent-400'
	});
</script>

{#if open}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div
		class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4"
		transition:fade={{ duration: 150 }}
		onmousedown={handleBackdropClick}
		onkeydown={(e) => e.key === 'Escape' && handleClose()}
	>
		<div
			class="max-h-[90vh] w-full max-w-lg overflow-hidden rounded-xl bg-theme-card shadow-xl"
			transition:scale={{ duration: 150, start: 0.95 }}
		>
			<!-- Header -->
			<div class="border-b border-theme px-6 py-4">
				<h2 class="text-lg font-semibold text-theme">{title}</h2>
				<p class="mt-1 text-sm text-theme-muted">{subtitle}</p>
			</div>

			<!-- Content -->
			<div class="max-h-[60vh] overflow-y-auto p-6">
				{#if loading}
					<div class="flex items-center justify-center py-8">
						<svg
							class="h-8 w-8 animate-spin text-primary-500"
							style="fill: none"
							viewBox="0 0 24 24"
						>
							<circle
								class="opacity-25"
								cx="12"
								cy="12"
								r="10"
								stroke="currentColor"
								stroke-width="4"
							></circle>
							<path
								class="opacity-75"
								fill="currentColor"
								d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
							></path>
						</svg>
					</div>
				{:else if !hasItems}
					<p class="py-8 text-center text-sm text-theme-muted italic">
						{emptyMessage}
					</p>
				{:else}
					<!-- Select All / None -->
					{#if selectAll && selectNone}
						<div class="mb-4 flex items-center gap-4">
							<button
								onclick={selectAll}
								class="text-sm font-medium hover:underline {colorClasses.selectAll}"
							>
								Select All
							</button>
							<button
								onclick={selectNone}
								class="text-sm font-medium text-theme-muted hover:underline"
							>
								Select None
							</button>
							<span class="ml-auto text-sm text-theme-muted">
								{selectedCount} selected
							</span>
						</div>
					{/if}

					<div class="space-y-2">
						{@render children()}
					</div>

					<!-- Selected Total -->
					{#if showTotal && selectedCount > 0}
						<div class="mt-4 rounded-lg p-3 {colorClasses.totalBg}">
							<div class="flex items-center justify-between">
								<span class="text-sm font-medium {colorClasses.totalText}"> Selected Total: </span>
								<span class="text-lg font-bold {colorClasses.totalText}">
									{formatCurrency(selectedTotal)}
								</span>
							</div>
						</div>
					{/if}
				{/if}

				{#if error}
					<div class="mt-4 rounded-lg bg-error-500/10 p-3">
						<p class="text-sm text-error-600 dark:text-error-400">{error}</p>
					</div>
				{/if}
			</div>

			<!-- Footer -->
			<div class="flex items-center justify-end gap-3 border-t border-theme px-6 py-4">
				<button onclick={handleClose} class="btn-ghost" disabled={saving}> Cancel </button>
				<button onclick={onSave} class="btn-primary" disabled={saving || selectedCount === 0}>
					{#if saving}
						Adding...
					{:else}
						Add {selectedCount}
						{selectedCount === 1 ? itemName : plural}
					{/if}
				</button>
			</div>
		</div>
	</div>
{/if}
