<script lang="ts">
	import { SvelteSet } from 'svelte/reactivity';

	interface Profile {
		id: string;
		fullName: string;
		email?: string | null;
		role?: string;
	}

	interface Props {
		label: string;
		profiles: Profile[];
		selectedIds: string[];
		placeholder?: string;
	}

	let { label, profiles, selectedIds = $bindable([]), placeholder = 'Search...' }: Props = $props();

	let searchQuery = $state('');
	let expanded = $state(false);
	let selectedSet = new SvelteSet<string>(selectedIds);

	// Sync external changes to internal set
	$effect(() => {
		const currentValues = [...selectedSet];
		const isSame =
			currentValues.length === selectedIds.length &&
			currentValues.every((v) => selectedIds.includes(v));
		if (!isSame) {
			selectedSet.clear();
			for (const v of selectedIds) {
				selectedSet.add(v);
			}
		}
	});

	// Sync internal set back to parent
	$effect(() => {
		const newSelected = [...selectedSet];
		if (
			newSelected.length !== selectedIds.length ||
			!newSelected.every((v) => selectedIds.includes(v))
		) {
			selectedIds = newSelected;
		}
	});

	let filteredProfiles = $derived(
		profiles.filter(
			(p) =>
				p.fullName.toLowerCase().includes(searchQuery.toLowerCase()) ||
				(p.email?.toLowerCase().includes(searchQuery.toLowerCase()) ?? false)
		)
	);

	function toggle(id: string) {
		if (selectedSet.has(id)) {
			selectedSet.delete(id);
		} else {
			selectedSet.add(id);
		}
	}

	function selectAll() {
		for (const profile of filteredProfiles) {
			selectedSet.add(profile.id);
		}
	}

	function selectNone() {
		selectedSet.clear();
	}

	function getSelectedNames(): string {
		if (selectedSet.size === 0) return 'None selected';
		if (selectedSet.size <= 2) {
			return profiles
				.filter((p) => selectedSet.has(p.id))
				.map((p) => p.fullName)
				.join(', ');
		}
		return `${selectedSet.size} selected`;
	}
</script>

<div class="space-y-2">
	<button
		type="button"
		class="flex w-full items-center justify-between rounded-lg border interactive px-4 py-2.5 text-left {selectedSet.size >
		0
			? 'border-primary-500 bg-primary-500/5'
			: 'border-theme bg-theme'}"
		onclick={() => (expanded = !expanded)}
	>
		<span class="flex flex-col">
			<span class="flex items-center gap-2">
				<span class="text-sm font-medium text-theme">{label}</span>
				{#if selectedSet.size > 0}
					<span
						class="inline-flex items-center rounded-full bg-primary-500 px-1.5 py-0.5 text-xs font-medium text-white"
					>
						{selectedSet.size}
					</span>
				{/if}
			</span>
			<span
				class="text-xs {selectedSet.size > 0
					? 'text-primary-600 dark:text-primary-400'
					: 'text-theme-muted'}">{getSelectedNames()}</span
			>
		</span>
		<svg
			class="h-5 w-5 text-theme-muted transition-transform {expanded ? 'rotate-180' : ''}"
			style="fill: none"
			viewBox="0 0 24 24"
			stroke="currentColor"
		>
			<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
		</svg>
	</button>

	{#if expanded}
		<div class="rounded-lg border border-theme bg-theme-card">
			<!-- Search -->
			<div class="border-b border-theme p-3">
				<div class="relative">
					<svg
						class="absolute top-1/2 left-3 h-4 w-4 -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"
						bind:value={searchQuery}
						{placeholder}
						class="placeholder-theme-muted w-full rounded-md border border-theme bg-theme py-1.5 pr-3 pl-9 text-sm text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
					/>
				</div>
			</div>

			<!-- Select All / None -->
			<div class="flex items-center gap-4 border-b border-theme px-3 py-2">
				<button
					type="button"
					onclick={selectAll}
					class="text-xs font-medium text-primary-600 hover:underline dark:text-primary-400"
				>
					Select All
				</button>
				<button
					type="button"
					onclick={selectNone}
					class="text-xs font-medium text-theme-muted hover:underline"
				>
					Select None
				</button>
				<span class="ml-auto text-xs text-theme-muted">{selectedSet.size} selected</span>
			</div>

			<!-- List -->
			<div class="max-h-48 overflow-y-auto">
				{#if filteredProfiles.length === 0}
					<p class="px-3 py-4 text-center text-sm text-theme-muted italic">No profiles found</p>
				{:else}
					{#each filteredProfiles as profile (profile.id)}
						<label class="flex cursor-pointer items-center gap-3 interactive px-3 py-2">
							<input
								type="checkbox"
								checked={selectedSet.has(profile.id)}
								onchange={() => toggle(profile.id)}
								class="border-theme-muted h-4 w-4 rounded text-primary-500 focus:ring-primary-500"
							/>
							<span class="min-w-0 flex-1">
								<span class="block truncate text-sm text-theme">{profile.fullName}</span>
								{#if profile.email}
									<span class="block truncate text-xs text-theme-muted">{profile.email}</span>
								{/if}
							</span>
							{#if profile.role}
								<span
									class="flex-shrink-0 rounded-full bg-gray-500/10 px-2 py-0.5 text-xs text-theme-muted"
								>
									{profile.role === 'ADMIN'
										? 'Admin'
										: profile.role === 'TEAM_LEADER'
											? 'Team Leader'
											: 'Member'}
								</span>
							{/if}
						</label>
					{/each}
				{/if}
			</div>
		</div>
	{/if}
</div>
