<script lang="ts" generics="T">
	import type { Snippet } from 'svelte';
	import { navigating } from '$app/state';
	import ContentContainer from '$lib/components/layout/ContentContainer.svelte';
	import MonthSelector from '$lib/components/team/MonthSelector.svelte';
	import StatusTabs from '$lib/components/team/StatusTabs.svelte';

	interface Props {
		title: string;
		subtitle: string;
		items: T[];
		currentStatus: string;
		currentMonth: string;
		counts?: {
			scheduled: number;
			inProgress: number;
			completed: number;
		};
		item: Snippet<[T]>;
		emptyIcon?: Snippet;
		emptyTitle?: string;
		emptyText?: string;
		colorScheme?:
			| 'primary'
			| 'secondary'
			| 'accent'
			| 'accent2'
			| 'accent3'
			| 'accent6'
			| 'accent7';
		// Admin-specific props
		searchQuery?: string;
		onSearchChange?: (query: string) => void;
		searchPlaceholder?: string;
		createButtonText?: string;
		onCreateClick?: () => void;
		emptyAction?: Snippet;
		headerActions?: Snippet;
		backHref?: string;
	}

	let {
		title,
		subtitle,
		items,
		currentStatus,
		currentMonth,
		counts,
		item,
		emptyIcon,
		emptyTitle = 'No items found',
		emptyText = 'There are no items matching your current filters.',
		colorScheme = 'primary',
		searchQuery = '',
		onSearchChange,
		searchPlaceholder = 'Search...',
		createButtonText,
		onCreateClick,
		emptyAction,
		headerActions,
		backHref = '/admin'
	}: Props = $props();

	let hasItems = $derived(items.length > 0);
	let isLoading = $derived(navigating.to !== null);

	const colorClasses: Record<string, string> = {
		primary: 'text-primary-600 dark:text-primary-400',
		secondary: 'text-secondary-600 dark:text-secondary-400',
		accent: 'text-accent-600 dark:text-accent-400',
		accent2: 'text-accent2-600 dark:text-accent2-400',
		accent3: 'text-accent3-600 dark:text-accent3-400',
		accent6: 'text-accent6-600 dark:text-accent6-400',
		accent7: 'text-accent7-600 dark:text-accent7-400'
	};

	function handleSearchInput(e: Event) {
		const target = e.target as HTMLInputElement;
		onSearchChange?.(target.value);
	}
</script>

<svelte:head>
	<title>{title} - Admin - Nexus</title>
</svelte:head>

<div class="py-8">
	<ContentContainer>
		<!-- Header -->
		<div class="mb-8">
			<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
				<div class="flex items-start gap-4">
					<a
						href={backHref}
						class="rounded-lg p-1 text-theme-muted hover:bg-black/5 hover:text-theme dark:hover:bg-white/10"
						aria-label="Go back"
					>
						<svg class="h-5 w-5" style="fill: none" stroke="currentColor" viewBox="0 0 24 24">
							<path
								stroke-linecap="round"
								stroke-linejoin="round"
								stroke-width="2"
								d="M15 19l-7-7 7-7"
							/>
						</svg>
					</a>
					<div>
						<h1 class="text-2xl font-bold md:text-3xl {colorClasses[colorScheme]}">{title}</h1>
						<p class="mt-2 text-theme-secondary">{subtitle}</p>
					</div>
				</div>
				<div class="hidden items-center gap-2 sm:flex">
					{#if headerActions}
						{@render headerActions()}
					{/if}
					{#if createButtonText && onCreateClick}
						<button
							type="button"
							onclick={onCreateClick}
							class="inline-flex shrink-0 items-center gap-2 rounded-lg bg-primary-500 px-4 py-2 whitespace-nowrap text-white transition-colors hover:bg-primary-600"
						>
							<svg class="h-5 w-5" style="fill: none" stroke="currentColor" viewBox="0 0 24 24">
								<path
									stroke-linecap="round"
									stroke-linejoin="round"
									stroke-width="2"
									d="M12 4v16m8-8H4"
								/>
							</svg>
							<span>{createButtonText}</span>
						</button>
					{/if}
				</div>
			</div>
		</div>

		<!-- Filters Row -->
		<div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
			<MonthSelector value={currentMonth} />
			<div class="sm:hidden">
				<StatusTabs current={currentStatus} {counts} compact />
			</div>
		</div>

		<!-- Mobile Header Actions -->
		{#if headerActions}
			<div class="mb-6 flex flex-wrap items-center gap-2 sm:hidden">
				{@render headerActions()}
			</div>
		{/if}

		<!-- Desktop Tabs -->
		<div class="mb-6 hidden sm:block">
			<StatusTabs current={currentStatus} {counts} />
		</div>

		<!-- Search -->
		{#if onSearchChange}
			<div class="mb-6">
				<div class="relative">
					<svg
						class="absolute top-1/2 left-3 h-5 w-5 -translate-y-1/2 text-theme-muted"
						style="fill: none"
						stroke="currentColor"
						viewBox="0 0 24 24"
					>
						<path
							stroke-linecap="round"
							stroke-linejoin="round"
							stroke-width="2"
							d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
						/>
					</svg>
					<input
						type="text"
						value={searchQuery}
						oninput={handleSearchInput}
						placeholder={searchPlaceholder}
						class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme-card py-2 pr-4 pl-10 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
					/>
				</div>
			</div>
		{/if}

		<!-- Content -->
		<div role="tabpanel" id="{currentStatus}-panel" class="relative">
			{#if isLoading}
				<!-- Loading Overlay -->
				<div
					class="bg-theme/50 absolute inset-0 z-10 flex min-h-[200px] items-start justify-center pt-12 backdrop-blur-sm"
				>
					<div class="flex flex-col items-center gap-3">
						<svg
							class="h-8 w-8 animate-spin text-theme-secondary"
							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>
						<span class="text-sm text-theme-secondary">Loading...</span>
					</div>
				</div>
			{/if}

			{#if hasItems}
				<div class="space-y-3">
					{#each items as itemData, index (index)}
						{@render item(itemData)}
					{/each}
				</div>
			{:else if !isLoading}
				<!-- Empty State (only show when not loading) -->
				<div class="empty-state">
					{#if emptyIcon}
						{@render emptyIcon()}
					{:else}
						<svg
							class="empty-state-icon"
							style="fill: none"
							stroke="currentColor"
							viewBox="0 0 24 24"
						>
							<path
								stroke-linecap="round"
								stroke-linejoin="round"
								stroke-width="1.5"
								d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
							/>
						</svg>
					{/if}
					<h2 class="empty-state-title">{emptyTitle}</h2>
					<p class="empty-state-text">{emptyText}</p>
					{#if emptyAction}
						{@render emptyAction()}
					{:else if createButtonText && onCreateClick && !searchQuery}
						<button
							type="button"
							onclick={onCreateClick}
							class="mt-4 inline-flex items-center gap-2 rounded-lg bg-primary-500 px-4 py-2 text-white transition-colors hover:bg-primary-600"
						>
							<svg class="h-5 w-5" style="fill: none" stroke="currentColor" viewBox="0 0 24 24">
								<path
									stroke-linecap="round"
									stroke-linejoin="round"
									stroke-width="2"
									d="M12 4v16m8-8H4"
								/>
							</svg>
							<span>{createButtonText}</span>
						</button>
					{/if}
				</div>
			{/if}
		</div>
	</ContentContainer>
</div>

<!-- Mobile FAB -->
{#if createButtonText && onCreateClick}
	<button
		type="button"
		onclick={onCreateClick}
		class="fixed right-4 bottom-20 z-30 flex h-14 w-14 items-center justify-center rounded-full bg-primary-500 text-white shadow-lg transition-colors hover:bg-primary-600 sm:hidden"
		aria-label={createButtonText}
	>
		<svg class="h-6 w-6" style="fill: none" stroke="currentColor" viewBox="0 0 24 24">
			<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
		</svg>
	</button>
{/if}
