<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, Search } from 'lucide-svelte';

	interface Props {
		/** Selected country code */
		value?: string;
		/** Callback when selection changes */
		onValueChange?: (code: string) => void;
		/** Placeholder text */
		placeholder?: string;
		/** Whether the select is disabled */
		disabled?: boolean;
		/** Additional classes */
		class?: string;
		/** Name for form submission */
		name?: string;
		/** Whether field is required */
		required?: boolean;
	}

	let {
		value = $bindable(''),
		onValueChange,
		placeholder = 'Select country...',
		disabled = false,
		class: className = '',
		name,
		required = false
	}: Props = $props();

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

	// Priority countries for Monaco USA members
	const priorityCountryCodes = ['US', 'MC', 'FR', 'GB', 'IT', 'CH', 'DE', 'ES'];

	// Sort countries with priority ones first
	const sortedCountries = $derived(() => {
		const priority = countries.filter(c => priorityCountryCodes.includes(c.code));
		const others = countries.filter(c => !priorityCountryCodes.includes(c.code));
		return [...priority, ...others];
	});

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

	// Get selected country
	const selectedCountry = $derived(countries.find((c) => c.code === value));

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

	function handleSelect(code: string) {
		value = code;
		onValueChange?.(code);
		open = false;
		searchValue = '';
	}
</script>

<div class={cn('w-full', className)}>
	<Combobox.Root
		type="single"
		bind:open
		onOpenChange={handleOpenChange}
		items={sortedCountries().map((c) => ({ value: c.code, label: c.name }))}
		bind:value
		onValueChange={(v) => v && handleSelect(v)}
	>
		<div class="relative" bind:this={anchorEl}>
			<Combobox.Trigger
				class={cn(
					'flex h-10 w-full items-center justify-between rounded-lg border border-slate-200 bg-white px-3 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}
			>
				{#if selectedCountry}
					<span class="flex items-center gap-2">
						<CountryFlag code={selectedCountry.code} size="md" />
						<span class="truncate">{selectedCountry.name}</span>
					</span>
				{:else}
					<span class="text-slate-400">{placeholder}</span>
				{/if}
				<ChevronDown
					class={cn('h-4 w-4 text-slate-400 transition-transform shrink-0', open && 'rotate-180')}
				/>
			</Combobox.Trigger>

			</div>
		<Combobox.Portal>
			<Combobox.Content
				customAnchor={anchorEl}
				sideOffset={8}
				class={cn(
					'z-[9999] w-[var(--bits-combobox-anchor-width)] 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'
				)}
			>
				<!-- Search Input -->
				<div class="border-b border-slate-100 p-2">
					<div class="relative">
						<Search class="pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
						<Combobox.Input
							class="h-9 w-full rounded-md border border-slate-200 bg-white pl-8 pr-3 text-sm placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-monaco-500"
							placeholder="Search countries..."
							oninput={(e) => {
								searchValue = e.currentTarget.value;
							}}
						/>
					</div>
				</div>

				<Combobox.Viewport class="max-h-[220px] 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 === country.code}
							<Combobox.Item
								value={country.code}
								label={country.name}
								class={cn(
									'flex cursor-pointer select-none items-center gap-3 rounded-lg px-3 py-2.5 text-sm outline-none transition-colors min-h-[44px]',
									'data-[highlighted]:bg-slate-100',
									isSelected && 'bg-monaco-50'
								)}
							>
								{#snippet children({ selected })}
									<CountryFlag code={country.code} size="md" />
									<span class="flex-1 truncate">{country.name}</span>
									{#if selected}
										<Check class="h-4 w-4 text-monaco-600 shrink-0" />
									{/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} {required} />
	{/if}
</div>
