<script lang="ts">
	import { Combobox } from 'bits-ui';
	import { countries } from '$lib/utils/countries';
	import CountryFlag from './CountryFlag.svelte';
	import { cn } from '$lib/utils';
	import { Check, ChevronDown, X, Search } from 'lucide-svelte';

	interface Props {
		/** Selected country codes */
		value?: string[];
		/** Callback when selection changes */
		onValueChange?: (codes: string[]) => void;
		/** Placeholder text */
		placeholder?: string;
		/** Whether the select is disabled */
		disabled?: boolean;
		/** Maximum number of selections allowed (0 = unlimited) */
		maxSelections?: number;
		/** Additional classes */
		class?: string;
		/** Name for form submission */
		name?: string;
	}

	let {
		value = $bindable([]),
		onValueChange,
		placeholder = 'Select nationalities...',
		disabled = false,
		maxSelections = 0,
		class: className = '',
		name
	}: Props = $props();

	let open = $state(false);
	let searchValue = $state('');
	let anchorEl = $state<HTMLElement>(null!);

	// Convert countries to combobox items format
	const countryItems = countries.map((c) => ({
		value: c.code,
		label: c.name
	}));

	// Filter countries based on search
	const filteredCountries = $derived(
		searchValue === ''
			? countries
			: countries.filter(
					(c) =>
						c.name.toLowerCase().includes(searchValue.toLowerCase()) ||
						c.code.toLowerCase().includes(searchValue.toLowerCase())
				)
	);

	function getCountry(code: string) {
		return countries.find((c) => c.code === code);
	}

	function toggleSelection(code: string) {
		if (value.includes(code)) {
			value = value.filter((v) => v !== code);
		} else if (maxSelections === 0 || value.length < maxSelections) {
			value = [...value, code];
		}
		onValueChange?.(value);
	}

	function removeSelection(code: string) {
		value = value.filter((v) => v !== code);
		onValueChange?.(value);
	}

	function handleOpenChange(newOpen: boolean) {
		open = newOpen;
		if (!newOpen) {
			searchValue = '';
		}
	}
</script>

<div class={cn('space-y-2', className)}>
	<!-- Selected Items -->
	{#if value.length > 0}
		<div class="flex flex-wrap gap-2">
			{#each value as code}
				{@const country = getCountry(code)}
				{#if country}
					<span
						class="inline-flex items-center gap-1.5 rounded-full bg-monaco-100 py-1 pl-2 pr-1 text-sm text-monaco-800"
					>
						<CountryFlag {code} size="sm" />
						<span class="max-w-[120px] truncate">{country.name}</span>
						<button
							type="button"
							onclick={() => removeSelection(code)}
							class="ml-0.5 rounded-full p-0.5 transition-colors hover:bg-monaco-200"
							{disabled}
						>
							<X class="h-3 w-3" />
						</button>
					</span>
				{/if}
			{/each}
		</div>
	{/if}

	<!-- Dropdown -->
	<Combobox.Root
		type="multiple"
		bind:open
		onOpenChange={handleOpenChange}
		items={countryItems}
		bind:value
		onValueChange={(v) => onValueChange?.(v)}
	>
		<div class="relative" bind:this={anchorEl}>
			<Combobox.Trigger
				class={cn(
					'flex h-11 w-full items-center rounded-lg border border-slate-200 bg-white text-sm',
					'ring-offset-white transition-colors',
					'focus:outline-none focus:ring-2 focus:ring-monaco-500 focus:ring-offset-2',
					'hover:border-slate-300',
					disabled && 'cursor-not-allowed opacity-50'
				)}
				{disabled}
			>
				<Search class="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
				<Combobox.Input
					class={cn(
						'h-full w-full bg-transparent pl-10 pr-10 text-sm outline-none',
						'placeholder:text-slate-400'
					)}
					placeholder={value.length > 0 ? 'Add more...' : placeholder}
					{disabled}
					oninput={(e) => {
						searchValue = e.currentTarget.value;
						if (!open) open = true;
					}}
				/>
				<ChevronDown
					class={cn('pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-500 transition-transform', open && 'rotate-180')}
				/>
			</Combobox.Trigger>

			</div>
		<Combobox.Portal>
			<Combobox.Content
				customAnchor={anchorEl}
				sideOffset={8}
				class={cn(
					'z-[9999] w-[var(--bits-combobox-anchor-width)] max-h-[220px] sm:max-h-[300px] overflow-hidden rounded-xl border border-slate-200 bg-white shadow-xl',
					'data-[state=open]:animate-in data-[state=closed]:animate-out',
					'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
					'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95'
				)}
			>
				<Combobox.Viewport class="max-h-[200px] sm:max-h-[280px] overflow-y-auto p-1">
					{#if filteredCountries.length === 0}
						<div class="px-3 py-6 text-center text-sm text-slate-500">
							No countries found
						</div>
					{:else}
						{#each filteredCountries as country (country.code)}
							{@const isSelected = value.includes(country.code)}
							{@const isDisabled = !isSelected && maxSelections > 0 && value.length >= maxSelections}
							<Combobox.Item
								value={country.code}
								label={country.name}
								disabled={isDisabled}
								class={cn(
									'flex cursor-pointer select-none items-center gap-3 rounded-lg px-3 py-3 sm:py-2.5 text-sm outline-none transition-colors min-h-[44px]',
									'data-[highlighted]:bg-slate-100',
									'data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',
									isSelected && 'bg-monaco-50'
								)}
							>
								{#snippet children({ selected })}
									<CountryFlag code={country.code} size="md" />
									<span class="flex-1">{country.name}</span>
									<span class="text-xs text-slate-400">{country.code}</span>
									{#if selected}
										<Check class="h-4 w-4 text-monaco-600" />
									{/if}
								{/snippet}
							</Combobox.Item>
						{/each}
					{/if}
				</Combobox.Viewport>
			</Combobox.Content>
		</Combobox.Portal>
	</Combobox.Root>

	<!-- Hidden input for form submission -->
	{#if name}
		<input type="hidden" {name} value={value.join(',')} />
	{/if}
</div>
