<script lang="ts">
	import * as Dialog from '$lib/components/ui/dialog';
	import { Button } from '$lib/components/ui/button';
	import { Input } from '$lib/components/ui/input';
	import { Loader2, Search } from 'lucide-svelte';
	import { countriesApi, type Country } from '$lib/api/dashboard/reference_data/countries';
	import { companyStore } from '$lib/stores/company.svelte';
	import { toast } from 'svelte-sonner';

	let {
		open = $bindable(),
		onSelect,
		onClear
	}: {
		open: boolean;
		onSelect: (country: Country) => void;
		onClear?: () => void;
	} = $props();

	let countries = $state<Country[]>([]);
	let loading = $state(false);
	let loadingMore = $state(false);
	let searchTerm = $state('');
	let previousSearchTerm = '';
	let page = $state(1);
	const pageSize = 100;
	let hasMore = $state(true);
	let totalItems = $state(0);
	let error = $state('');
	let observer: IntersectionObserver | null = null;
	let bottomSentinel: HTMLElement | null = $state(null);
	let searchTimeout: ReturnType<typeof setTimeout> | undefined;
	let isInitialized = false;

	async function resetAndLoad() {
		page = 1;
		countries = [];
		hasMore = true;
		await loadCountries(true);
	}

	async function loadMore() {
		if (!hasMore || loading || loadingMore) return;
		page += 1;
		await loadCountries(false);
	}

	async function loadCountries(isInitial: boolean) {
		if (isInitial) {
			loading = true;
		} else {
			loadingMore = true;
		}
		error = '';
		try {
			const companyId = companyStore.activeCompany?.id;
			if (!companyId) {
				error = 'No hay una empresa activa seleccionada';
				return;
			}

			const response = await countriesApi.list(companyId, page, pageSize, searchTerm);

			if (response.data) {
				const newItems = response.data.items || [];
				totalItems = response.data.total || 0;
				if (isInitial) {
					countries = newItems;
				} else {
					countries = [...countries, ...newItems];
				}
				hasMore = countries.length < totalItems && newItems.length > 0;
			} else if (response.error) {
				error = `Error: ${response.error}`;
				toast.error(error);
			}
		} catch (err) {
			error = 'Error loading countries';
			console.error('Error loading countries:', err);
			toast.error(error);
		} finally {
			loading = false;
			loadingMore = false;
		}
	}

	function handleSelect(country: Country) {
		onSelect(country);
		open = false;
	}

	function handleRowKeydown(event: KeyboardEvent, country: Country) {
		if (event.key === 'Enter' || event.key === ' ') {
			event.preventDefault();
			handleSelect(country);
		}
	}

	$effect(() => {
		if (open && !isInitialized) {
			isInitialized = true;
			previousSearchTerm = searchTerm;
			void resetAndLoad();
		} else if (!open) {
			isInitialized = false;
		}
	});

	$effect(() => {
		const term = searchTerm;
		if (isInitialized && term !== previousSearchTerm) {
			if (searchTimeout) clearTimeout(searchTimeout);
			searchTimeout = setTimeout(() => {
				previousSearchTerm = term;
				void resetAndLoad();
			}, 400);
		}
	});

	$effect(() => {
		if (bottomSentinel && hasMore && !loading && !loadingMore && open) {
			if (observer) observer.disconnect();

			observer = new IntersectionObserver(
				(entries) => {
					if (entries[0]?.isIntersecting && hasMore && !loading && !loadingMore) {
						void loadMore();
					}
				},
				{ threshold: 0.1 }
			);

			observer.observe(bottomSentinel);
		}

		return () => {
			if (observer) observer.disconnect();
		};
	});
</script>

<Dialog.Root bind:open>
	<Dialog.Content class="!max-w-[70vw] w-[70vw] max-h-[90vh] p-0 flex flex-col">
		<Dialog.Header class="px-6 py-4 border-b">
			<Dialog.Title class="text-lg font-semibold">CATALOGO DE PAISES</Dialog.Title>
		</Dialog.Header>

		<div class="px-6 py-3 border-b bg-zinc-50 dark:bg-zinc-900">
			<div class="flex items-center gap-2">
				<Search class="w-4 h-4 text-zinc-400" />
				<Input
					bind:value={searchTerm}
					placeholder="Buscar por clave M3, MEX, AME o descripción..."
					class="flex-1 h-9"
					type="search"
				/>
			</div>
			<p class="mt-2 text-xs text-zinc-500">
				{totalItems > 0 ? `${countries.length} de ${totalItems} mostrados` : ''} — desplázate para cargar
				más; el catálogo completo supera 100 países.
			</p>
		</div>

		<div class="flex-1 overflow-auto px-6 py-4">
			{#if loading && countries.length === 0}
				<div class="flex items-center justify-center py-20">
					<Loader2 class="w-8 h-8 animate-spin text-zinc-900 dark:text-zinc-100" />
				</div>
			{:else if error}
				<div class="flex items-center justify-center py-20 text-red-600">
					<p>{error}</p>
				</div>
			{:else}
				<div class="border rounded-md overflow-hidden">
					<table class="w-full text-sm">
						<thead class="bg-zinc-900 dark:bg-zinc-800 text-white">
							<tr>
								<th class="px-3 py-2 text-left font-semibold border-r border-zinc-700"
									>Clave M3</th
								>
								<th class="px-3 py-2 text-left font-semibold border-r border-zinc-700"
									>Clave Mexicana</th
								>
								<th class="px-3 py-2 text-left font-semibold border-r border-zinc-700"
									>Descripción Español</th
								>
								<th class="px-3 py-2 text-left font-semibold border-r border-zinc-700"
									>Clave Americana</th
								>
								<th class="px-3 py-2 text-left font-semibold">Descripción Inglés</th>
							</tr>
						</thead>
						<tbody>
							{#each countries as country}
								<tr
									class="border-b hover:bg-zinc-100 dark:hover:bg-zinc-800 cursor-pointer transition-colors"
									tabindex="0"
									onclick={() => handleSelect(country)}
									onkeydown={(event) => handleRowKeydown(event, country)}
								>
									<td class="px-3 py-2 border-r">{country.m3_key || ''}</td>
									<td class="px-3 py-2 border-r">{country.mex_key || ''}</td>
									<td class="px-3 py-2 border-r">{country.description_es || ''}</td>
									<td class="px-3 py-2 border-r text-center">{country.ame_key || ''}</td>
									<td class="px-3 py-2">{country.description_en || ''}</td>
								</tr>
							{/each}
							{#if countries.length === 0}
								<tr>
									<td colspan="5" class="px-3 py-8 text-center text-zinc-500">
										No se encontraron resultados
									</td>
								</tr>
							{/if}
						</tbody>
					</table>
				</div>

				<div
					bind:this={bottomSentinel}
					class="h-10 flex items-center justify-center"
					aria-hidden="true"
				>
					{#if loadingMore}
						<Loader2 class="h-5 w-5 animate-spin text-zinc-500" />
					{/if}
				</div>

				<div class="mt-4 text-sm text-zinc-600 dark:text-zinc-400">
					Usa flechas para navegar filas y Enter/Espacio para seleccionar.
				</div>
			{/if}
		</div>

		<div class="px-6 py-3 border-t bg-zinc-50 dark:bg-zinc-900 flex items-center justify-end gap-2">
			{#if onClear}
				<Button variant="ghost" size="sm" onclick={() => { onClear(); open = false; }}>Quitar selección</Button>
			{/if}
			<Button variant="outline" size="sm" onclick={() => (open = false)}>Cerrar</Button>
		</div>
	</Dialog.Content>
</Dialog.Root>
