<script lang="ts">
	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 { Loader2, Plus, Search, Trash2, Edit } from 'lucide-svelte';
	import {
		getTariffFractions,
		deleteTariffFraction,
		type TariffFraction
	} from '$lib/api/dashboard/a76/general_catalogs/tariff-fractions';
	import { companyStore } from '$lib/stores/company.svelte';
	import { untrack } from 'svelte';
	import * as AlertDialog from '$lib/components/ui/alert-dialog';
	import TariffFractionFormDialog from './TariffFractionFormDialog.svelte';
	import SitarFractionTabs from './SitarFractionTabs.svelte';
	import { toast } from 'svelte-sonner';
	import { currentUser } from '$lib/auth';
	import ErrorState from '$lib/components/dashboard/common/error-state.svelte';
	import {
		canCreateTariffFractionCatalog,
		canDeleteTariffFractionCatalog,
		canEditTariffFractionCatalog,
		canViewTariffFractionCatalog,
		resolveTariffFractionBasePrefix
	} from '$lib/permissions/tariff-fraction-permissions';
	import {
		getTariffFractionDisplayFraction,
		getTariffFractionDisplayKey
	} from '$lib/utils/tariff-fraction-display';

	let {
		title = 'Fracciones Arancelarias',
		catalog = 'mex', // 'mex' or 'usa'
		levelFilter = null, // null or number
		readOnly = false,
		basePerm: customBasePerm = null,
		showSitarTabsOnSelect = false
	}: {
		title?: string;
		catalog?: string;
		levelFilter?: number | null;
		readOnly?: boolean;
		basePerm?: string | null;
		showSitarTabsOnSelect?: boolean;
	} = $props();

	let fractions = $state<TariffFraction[]>([]);
	let totalFractions = $state(0);
	let currentPage = $state(1);
	let pageSize = 50;
	let isLoading = $state(false);
	let error = $state<string | null>(null);
	let status = $state<number>(200);

	// Permisos (prefijo RBAC por catálogo o basePerm override, p. ej. frac_sitar_7)
	const basePrefix = $derived(resolveTariffFractionBasePrefix(catalog, customBasePerm));

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

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

	let search = $state('');
	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);

	let isFormDialogOpen = $state(false);
	let selectedFraction = $state<TariffFraction | null>(null);
	let selectedDetailFraction = $state<TariffFraction | null>(null);
	let isManageMode = $state(false); // If true, opens form in edit mode

	// Delete confirmation
	let showDeleteConfirm = $state(false);
	let fractionToDelete = $state<TariffFraction | null>(null);

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

		isLoading = true;
		error = null;

		if (reset) {
			currentPage = 1;
			fractions = [];
			hasMore = true;
		}

		try {
			const filters: Record<string, any> = {};
			if (search) filters.search = search;
			if (levelFilter !== null) filters.level = levelFilter;
			filters.catalog = catalog;

			const response = await getTariffFractions(currentPage, pageSize, companyId, filters);
			const payload = (response.data || response) as any;

			if (payload?.items) {
				const newItems = payload.items || [];
				if (reset) {
					fractions = newItems;
				} else {
					fractions = [...fractions, ...newItems];
				}
				if (selectedDetailFraction) {
					selectedDetailFraction =
						[...fractions, ...newItems].find((item) => item.id === selectedDetailFraction?.id) ||
						selectedDetailFraction;
				}
				totalFractions = payload.total || 0;

				// Safer end-of-data detection
				hasMore = newItems.length === pageSize && fractions.length < totalFractions;
			} else {
				if (reset) fractions = [];
				hasMore = false;
				if (response.error) {
					error = response.error;
					status = (response as any).status || 500;
				}
			}
		} catch (err: any) {
			console.error('Error loading fractions:', err);
			error = err.message || 'Error al cargar las fracciones';
			status = err.status || 500;
			hasMore = false;
		} finally {
			isLoading = false;
		}
	}

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

	function handlePageChange(newPage: number) {
		currentPage = newPage;
		loadFractions();
	}

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

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

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

	function openCreateDialog() {
		if (!canCreate) {
			toast.error('No tienes permiso para crear fracciones en este catálogo');
			return;
		}
		selectedFraction = null;
		isManageMode = false; // Create mode
		isFormDialogOpen = true;
	}

	function openEditDialog(fraction: TariffFraction) {
		if (!canEdit) {
			toast.error('No tienes permiso para editar fracciones en este catálogo');
			return;
		}
		selectedFraction = fraction;
		isManageMode = true; // Edit mode
		isFormDialogOpen = true;
	}

	function selectFractionDetail(fraction: TariffFraction) {
		if (!showSitarTabsOnSelect) return;
		selectedDetailFraction = fraction;
	}

	function confirmDelete(fraction: TariffFraction) {
		if (!canDelete) {
			toast.error('No tienes permiso para eliminar fracciones en este catálogo');
			return;
		}
		fractionToDelete = fraction;
		showDeleteConfirm = true;
	}

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

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

	// Reload when company changes
	$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">{title}</h1>
			<p class="text-sm text-muted-foreground">
				Gestiona las fracciones arancelarias de la tarifa.
			</p>
		</div>
		<div class="flex items-center gap-3">
			{#if !isError && !readOnly && canCreate}
				<Button class="h-9" onclick={openCreateDialog}>
					<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}

		{#if error}
			<div class="flex-none rounded-md border border-destructive px-4 py-3 text-sm text-destructive">
				{error}
			</div>
		{/if}

		<div class="grid min-h-0 flex-1 grid-cols-1 gap-4 xl:grid-cols-12">
		<Card.Root class="border bg-background flex min-h-0 flex-1 flex-col overflow-hidden xl:col-span-8">
			<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 h-4 w-4 text-muted-foreground" />
							<Input placeholder="Buscar..." class="h-9 w-40 bg-card pl-8 lg:w-56" bind:value={search} oninput={handleSearchInput} />
						</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">Clave</TableHead>
								<TableHead class="catalog-table-head-cell">Fracción</TableHead>
								<TableHead class="catalog-table-head-cell">Descripción</TableHead>
								{#if catalog === 'mex'}
									<TableHead class="catalog-table-head-cell">NICO</TableHead>
									<TableHead class="catalog-table-head-cell">U.M.T</TableHead>
								{:else if catalog === 'usa' || catalog === 'american' || catalog === 'canadian'}
									<TableHead class="catalog-table-head-cell">Unidad</TableHead>
								{/if}
								<TableHead class="catalog-table-head-cell">Adv. Impo</TableHead>
								<TableHead class="catalog-table-head-cell">Adv. Expo</TableHead>
								{#if !readOnly && (canEdit || canDelete)}
									<TableHead class="catalog-table-head-cell w-[100px]">Acciones</TableHead>
								{/if}
							</TableRow>
						</TableHeader>
						<TableBody>
							{#if fractions.length === 0 && !isLoading}
								<TableRow>
									<TableCell
										colspan={catalog === 'mex' ? (readOnly ? 7 : 8) : readOnly ? 6 : 7}
										class="h-24 text-center"
									>
										No se encontraron resultados
									</TableCell>
								</TableRow>
							{:else}
								{#each fractions as fraction (fraction.id)}
									<TableRow
										class="catalog-table-row {selectedDetailFraction?.id === fraction.id ? 'bg-muted/40' : ''}"
										onclick={() => selectFractionDetail(fraction)}
									>
										<TableCell class="font-mono">{getTariffFractionDisplayKey(fraction)}</TableCell>
										<TableCell class="font-medium">{getTariffFractionDisplayFraction(fraction)}</TableCell>
										<TableCell class="max-w-md truncate" title={fraction.description}>
											{fraction.description}
										</TableCell>
										{#if catalog === 'mex'}
											<TableCell>{fraction.nico || '-'}</TableCell>
											<TableCell>{fraction.umt || '-'}</TableCell>
										{:else if catalog === 'usa' || catalog === 'american' || catalog === 'canadian'}
											<TableCell>{fraction.umt || '-'}</TableCell>
										{/if}
										<TableCell>{fraction.adv_impo || '-'}</TableCell>
										<TableCell>{fraction.adv_expo || '-'}</TableCell>
										{#if (!readOnly && (canEdit || canDelete))}
											<TableCell>
												<div class="flex items-center gap-2">
													{#if canEdit}
														<Button variant="ghost" size="icon" onclick={() => openEditDialog(fraction)}>
															<Edit class="h-4 w-4" />
														</Button>
													{/if}
													{#if canDelete}
														<Button
															variant="ghost"
															size="icon"
															class="text-destructive hover:text-destructive"
															onclick={() => confirmDelete(fraction)}
														>
															<Trash2 class="h-4 w-4" />
														</Button>
													{/if}
												</div>
											</TableCell>
										{/if}
									</TableRow>
								{/each}
							{/if}
							{#if isLoading}
								<TableRow>
									<TableCell
										colspan={catalog === 'mex' ? (readOnly ? 7 : 8) : readOnly ? 6 : 7}
										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>
		{#if showSitarTabsOnSelect}
			<div class="min-h-0 xl:col-span-4 flex flex-col overflow-hidden">
				<SitarFractionTabs selectedFraction={selectedDetailFraction} {catalog} />
			</div>
		{/if}
		</div>

		<div class="flex-none text-sm text-muted-foreground">Mostrando {fractions.length} de {totalFractions} 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 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>

{#if isFormDialogOpen}
	<TariffFractionFormDialog
		bind:open={isFormDialogOpen}
		fraction={selectedFraction}
		{catalog}
		catalogBasePrefix={basePrefix}
		onSuccess={() => {
			loadFractions(true);
			isFormDialogOpen = false;
		}}
	/>
{/if}
