<script lang="ts">
	import { untrack } from 'svelte';
	import {
		getCanadianFractions,
		deleteCanadianFraction,
		type CanadianFraction
	} from '$lib/api/dashboard/general_catalogs/canadian';
	import { Input } from '$lib/components/ui/input';
	import { Button } from '$lib/components/ui/button';
	import * as Card from '$lib/components/ui/card';
	import {
		Table,
		TableBody,
		TableCell,
		TableHead,
		TableHeader,
		TableRow
	} from '$lib/components/ui/table';
	import { Search, Loader2, Plus, Pencil, Trash2 } from 'lucide-svelte';
	import { toast } from 'svelte-sonner';
	import CanadianFractionDialog from './CanadianFractionDialog.svelte';
	import { companyStore } from '$lib/stores/company.svelte';
	import { currentUser } from '$lib/auth';
	import ErrorState from '$lib/components/dashboard/common/error-state.svelte';
	import {
		canCreateTariffFractionCatalog,
		canDeleteTariffFractionCatalog,
		canEditTariffFractionCatalog,
		canViewTariffFractionCatalog
	} from '$lib/permissions/tariff-fraction-permissions';
	import * as AlertDialog from '$lib/components/ui/alert-dialog';

	let fractions = $state<CanadianFraction[]>([]);
	let loading = $state(false);
	let searchQuery = $state('');
	let page = $state(1);
	let totalItems = $state(0);
	let totalPages = $state(0);
	let pageSize = 50;
	let error = $state<string | null>(null);
	let status = $state<number>(200);

	let searchTimeout: ReturnType<typeof setTimeout>;
	let observer: IntersectionObserver;
	let sentinel = $state<HTMLDivElement | null>(null);
	let scrollContainer = $state<HTMLDivElement | null>(null);

	// Infinite scroll state
	let hasMore = $state(true);

	// Dialog state
	let dialogOpen = $state(false);
	let editingFraction = $state<CanadianFraction | null>(null);
	let deletingFractionId = $state<number | null>(null);
	let showDeleteConfirm = $state(false);
	let fractionToDelete = $state<CanadianFraction | null>(null);

	const FRAC_CA = 'frac_canadian';

	// Permissions
	const canView = $derived(canViewTariffFractionCatalog($currentUser, FRAC_CA));
	const canCreate = $derived(canCreateTariffFractionCatalog($currentUser, FRAC_CA));
	const canEdit = $derived(canEditTariffFractionCatalog($currentUser, FRAC_CA));
	const canDelete = $derived(canDeleteTariffFractionCatalog($currentUser, FRAC_CA));

	const isError = $derived(!canView || status >= 400 || error);

	async function loadFractions(reset = false) {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;
		if (loading) return;

		loading = true;
		error = null;

		if (reset) {
			page = 1;
			fractions = [];
			hasMore = true;
		} else {
			page++;
		}

		try {
			const response = await getCanadianFractions(
				companyId,
				page,
				pageSize,
				searchQuery || undefined
			);

			const newItems = response.items || [];
			if (reset) {
				fractions = newItems;
			} else {
				fractions = [...fractions, ...newItems];
			}

			totalItems = response.total;
			totalPages = response.pages;

			// Safer end-of-data detection
			hasMore = newItems.length === pageSize && fractions.length < totalItems;
		} catch (err: any) {
			console.error('Error loading Canadian fractions:', err);
			error = err.message || 'Error al cargar fracciones canadienses';
			status = err.status || 500;
			hasMore = false;
		} finally {
			loading = false;
		}
	}

	function handleSearchInput() {
		clearTimeout(searchTimeout);
		searchTimeout = setTimeout(() => {
			loadFractions(true);
		}, 500);
	}

	function handleKeyDown(event: KeyboardEvent) {
		if (event.key === 'Enter') {
			clearTimeout(searchTimeout);
			loadFractions(true);
		}
	}

	function handleCreate() {
		if (!canCreate) {
			toast.error('No tienes permiso para crear fracciones canadienses');
			return;
		}
		editingFraction = null;
		dialogOpen = true;
	}

	function handleEdit(fraction: CanadianFraction) {
		if (!canEdit) {
			toast.error('No tienes permiso para editar fracciones canadienses');
			return;
		}
		editingFraction = fraction;
		dialogOpen = true;
	}

	function confirmDelete(fraction: CanadianFraction) {
		if (!canDelete) {
			toast.error('No tienes permiso para eliminar fracciones canadienses');
			return;
		}
		fractionToDelete = fraction;
		showDeleteConfirm = true;
	}

	async function handleDelete() {
		if (!canDelete || !fractionToDelete || !companyStore.activeCompany?.id) return;

		try {
			deletingFractionId = fractionToDelete.id;
			await deleteCanadianFraction(companyStore.activeCompany.id, fractionToDelete.id);
			toast.success('Fracción eliminada correctamente');
			loadFractions(true);
		} catch (err: any) {
			console.error('Error deleting Canadian fraction:', err);
			const msg = err.status === 403 
				? 'No tienes permiso para eliminar este registro'
				: 'Error al eliminar la fracción';
			toast.error(msg);
		} finally {
			deletingFractionId = null;
			showDeleteConfirm = false;
			fractionToDelete = null;
		}
	}

	function handleSuccess() {
		loadFractions(true);
	}

	function setupObserver() {
		if (observer) observer.disconnect();

		observer = new IntersectionObserver(
			(entries) => {
				if (entries[0].isIntersecting && hasMore && !loading && fractions.length > 0) {
					loadFractions(false);
				}
			},
			{ root: scrollContainer || null, rootMargin: '100px' }
		);

		if (sentinel) observer.observe(sentinel);
	}

	$effect(() => {
		const companyId = companyStore.activeCompany?.id;
		if (companyId) {
			untrack(() => loadFractions(true));
		}
	});

	// Setup observer only when sentinel is available
	$effect(() => {
		if (sentinel) {
			setupObserver();
			return () => observer?.disconnect();
		}
	});
</script>

<div class="flex flex-col gap-6 p-6 h-[calc(100svh-4rem)] group-has-data-[collapsible=icon]/sidebar-wrapper:h-[calc(100svh-3rem)] overflow-hidden">
	<div class="flex items-center justify-between gap-4">
		<div class="space-y-1">
			<h1 class="text-2xl font-bold tracking-tight">Listado de Fracciones Canadienses</h1>
			<p class="text-sm text-muted-foreground">
				Gestiona las fracciones arancelarias de la tarifa canadiense.
			</p>
		</div>
		<div class="flex items-center gap-3">
			{#if !isError && canCreate}
				<Button class="h-9" onclick={handleCreate}>
					<Plus class="mr-2 h-4 w-4" />
					Nueva Fracción
				</Button>
			{/if}
		</div>
	</div>

	{#if isError}
		<ErrorState
			status={!canView ? 403 : status}
			error={!canView ? 'No tienes permiso para ver este catálogo' : (error || '')}
			onRetry={() => loadFractions(true)}
		/>
	{:else}
		<Card.Root class="border bg-background flex min-h-0 flex-1 flex-col overflow-hidden shadow-sm">
			<Card.Header>
				<div class="flex flex-wrap items-center justify-end gap-3">
					<div class="flex flex-wrap items-center gap-2">
						<div class="relative">
							<Search class="absolute top-2.5 left-2.5 h-4 w-4 text-muted-foreground" />
							<Input
								id="search-fraction"
								type="text"
								placeholder="Buscar..."
								class="h-9 w-44 bg-card pl-9 lg:w-64"
								bind:value={searchQuery}
								oninput={handleSearchInput}
								onkeydown={handleKeyDown}
							/>
						</div>
					</div>
				</div>
			</Card.Header>
			<Card.Content class="min-h-0 p-0 overflow-hidden flex-1 flex flex-col">
				<div class="catalog-table-shell flex min-h-0 flex-1 flex-col overflow-hidden border-none">
					<div class="flex-1 overflow-auto" bind:this={scrollContainer}>
						<Table>
							<TableHeader class="catalog-table-header sticky top-0 bg-background z-10">
								<TableRow>
									<TableHead class="catalog-table-head-cell">Fracción</TableHead>
									<TableHead class="catalog-table-head-cell">Descripción</TableHead>
									<TableHead class="catalog-table-head-cell">País</TableHead>
									<TableHead class="catalog-table-head-cell">Unidad</TableHead>
									<TableHead class="catalog-table-head-cell text-right">ADV</TableHead>
									{#if canEdit || canDelete}
										<TableHead class="catalog-table-head-cell w-[100px]">Acciones</TableHead>
									{/if}
								</TableRow>
							</TableHeader>
							<TableBody>
								{#if fractions.length === 0 && !loading}
									<TableRow>
										<TableCell colspan={canEdit || canDelete ? 6 : 5} class="h-24 text-center">No se encontraron resultados</TableCell>
									</TableRow>
								{:else}
									{#each fractions as fraction}
										<TableRow class="catalog-table-row">
											<TableCell class="font-medium">{fraction.fraction}</TableCell>
											<TableCell class="max-w-md truncate" title={fraction.description}>{fraction.description || '-'}</TableCell>
											<TableCell>{fraction.country_code}</TableCell>
											<TableCell>{fraction.unit_of_measure || '-'}</TableCell>
											<TableCell class="text-right">{fraction.ad_valorem ?? '-'}</TableCell>
											{#if canEdit || canDelete}
												<TableCell>
													<div class="flex items-center gap-2">
														{#if canEdit}
															<Button variant="ghost" size="icon" class="h-8 w-8" onclick={() => handleEdit(fraction)}>
																<Pencil class="h-4 w-4" />
															</Button>
														{/if}
														{#if canDelete}
															<Button
																variant="ghost"
																size="icon"
																class="h-8 w-8 text-destructive hover:text-destructive"
																onclick={() => confirmDelete(fraction)}
																disabled={deletingFractionId === fraction.id}
															>
																{#if deletingFractionId === fraction.id}
																	<Loader2 class="h-4 w-4 animate-spin" />
																{:else}
																	<Trash2 class="h-4 w-4" />
																{/if}
															</Button>
														{/if}
													</div>
												</TableCell>
											{/if}
										</TableRow>
									{/each}
								{/if}
								{#if loading}
									<TableRow>
										<TableCell colspan={canEdit || canDelete ? 6 : 5} class="h-24 text-center">
											<div class="flex justify-center">
												<Loader2 class="h-6 w-6 animate-spin" />
											</div>
										</TableCell>
									</TableRow>
								{/if}
							</TableBody>
						</Table>
						<div bind:this={sentinel} class="h-4 w-full"></div>
					</div>
				</div>
			</Card.Content>
		</Card.Root>

		<div class="flex-none text-sm text-muted-foreground mt-2">Mostrando {fractions.length} de {totalItems} registros</div>
	{/if}
</div>

<AlertDialog.Root bind:open={showDeleteConfirm}>
	<AlertDialog.Content>
		<AlertDialog.Header>
			<AlertDialog.Title>¿Estás seguro?</AlertDialog.Title>
			<AlertDialog.Description>
				Esta acción no se puede deshacer. Se eliminará la fracción arancelaria canadiense permanentemente.
			</AlertDialog.Description>
		</AlertDialog.Header>
		<AlertDialog.Footer>
			<AlertDialog.Cancel>Cancelar</AlertDialog.Cancel>
			<AlertDialog.Action
				class="text-destructive-foreground bg-destructive hover:bg-destructive/90"
				onclick={handleDelete}
			>
				Eliminar
			</AlertDialog.Action>
		</AlertDialog.Footer>
	</AlertDialog.Content>
</AlertDialog.Root>

<CanadianFractionDialog
	bind:open={dialogOpen}
	fraction={editingFraction}
	onSuccess={handleSuccess}
/>
