<script lang="ts">
	import { userHasSectorsCatalogAction } from '$lib/permissions/catalogs/sectors-catalog-permissions';

	import { Input } from '$lib/components/ui/input';
	import * as Table from '$lib/components/ui/table';
	import * as Card from '$lib/components/ui/card';
	import { untrack } from 'svelte';
	import { toast } from 'svelte-sonner';
	import { getSectors, type Sector } from '$lib/api/dashboard/general_catalogs/sectors';
	import { Loader2, Search } from 'lucide-svelte';
	import Badge from '$lib/components/ui/badge/badge.svelte';
	import { companyStore } from '$lib/stores/company.svelte';
	import ErrorState from '$lib/components/dashboard/common/error-state.svelte';
	import { currentUser, userHasPermission } from '$lib/auth';
	let { title = 'Sectores' }: { title?: string } = $props();

	let sectors = $state<Sector[]>([]);
	let loading = $state(false);
	let error = $state<string | null>(null);
	let status = $state<number>(200);

	// Permisos
	const canView = $derived(userHasPermission($currentUser, 'ref_sectors.view'));
	const canCreate = $derived(userHasSectorsCatalogAction($currentUser, 'create'));
	const canEdit = $derived(userHasSectorsCatalogAction($currentUser, 'edit'));
	const canDelete = $derived(userHasSectorsCatalogAction($currentUser, 'delete'));
	const isError = $derived(!canView || status >= 400 || error);

	let searchTerm = $state('');
	let page = $state(1);
	let pageSize = 50;
	let hasMore = $state(true);
	let total = $state(0);
	let searchTimeout: ReturnType<typeof setTimeout>;
	let observer: IntersectionObserver;
	let sentinel = $state<HTMLDivElement | null>(null);

	async function loadSectors(reset = false) {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId || !canView) return;
		if (loading || (!hasMore && !reset)) return;
		
		loading = true;
		error = null;

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

		try {
			const response = await getSectors(page, pageSize, companyId, searchTerm || undefined);

			if (response.data) {
				status = 200;
				const newItems = response.data.items || [];
				if (reset) {
					sectors = newItems;
				} else {
					sectors = [...sectors, ...newItems];
				}

				total = response.data.total;
				hasMore = newItems.length === pageSize && sectors.length < total;
			} else {
				error = response.error || 'Failed to load';
				status = response.status || 500;
				hasMore = false;
			}
		} catch (err: any) {
			console.error('Error loading sectors:', err);
			error = err.message || 'Error al cargar sectores';
			status = err.status || 500;
			hasMore = false;
		} finally {
			loading = false;
		}
	}

	function handleSearch() {
		loadSectors(true);
	}

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

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

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

		observer = new IntersectionObserver(
			(entries) => {
				if (entries[0].isIntersecting && hasMore && !loading && sectors.length > 0) {
					loadSectors(false);
				}
			},
			{ rootMargin: '100px' }
		);

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

	// Initial load and reload when company changes
	$effect(() => {
		const id = companyStore.activeCompany?.id;
		if (id) {
			untrack(() => loadSectors(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 los sectores de la tarifa.
			</p>
		</div>
	</div>

	{#if isError}
		<ErrorState 
			status={!canView ? 403 : status} 
			error={!canView ? 'No tienes permiso para ver este catálogo' : (error || '')} 
			onRetry={() => loadSectors(true)} 
		/>
	{:else}

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

		<Card.Root class="border bg-background flex min-h-0 flex-1 flex-col overflow-hidden">
			<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
								placeholder="Buscar por clave o descripción..."
								class="h-9 w-44 bg-card pl-8 lg:w-64"
								bind:value={searchTerm}
								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 text-nowrap">
					<div class="min-h-0 flex-1 overflow-auto">
					<Table.Root>
						<Table.Header class="catalog-table-header">
							<Table.Row inTabOrder={false}>
								<Table.Head class="catalog-table-head-cell w-[100px]">Clave</Table.Head>
								<Table.Head class="catalog-table-head-cell">Descripción</Table.Head>
								<Table.Head class="catalog-table-head-cell text-right">Estatus</Table.Head>
							</Table.Row>
						</Table.Header>
						<Table.Body>
							{#if loading && page === 1}
								<Table.Row inTabOrder={false}>
									<Table.Cell colspan={3} class="h-24 text-center">
										<div class="flex justify-center">
											<Loader2 class="h-6 w-6 animate-spin" />
										</div>
									</Table.Cell>
								</Table.Row>
							{:else if sectors.length === 0}
								<Table.Row inTabOrder={false}>
									<Table.Cell colspan={3} class="h-24 text-center">
										No se encontraron sectores.
									</Table.Cell>
								</Table.Row>
							{:else}
								{#each sectors as sector}
									<Table.Row inTabOrder={false} class="catalog-table-row">
										<Table.Cell class="font-medium">{sector.key}</Table.Cell>
										<Table.Cell>{sector.description}</Table.Cell>
										<Table.Cell class="text-right">
											{#if sector.authorized}
												<Badge variant="default">Autorizado</Badge>
											{:else}
												<Badge variant="secondary">No Autorizado</Badge>
											{/if}
										</Table.Cell>
									</Table.Row>
								{/each}
							{/if}
							{#if loading && page > 1}
								<Table.Row inTabOrder={false}>
									<Table.Cell colspan={3} class="h-12 text-center">
										<div class="flex justify-center">
											<Loader2 class="h-4 w-4 animate-spin" />
										</div>
									</Table.Cell>
								</Table.Row>
							{/if}
						</Table.Body>
					</Table.Root>
					</div>
				</div>
			</Card.Content>
		</Card.Root>

		<div class="flex-none text-sm text-muted-foreground">Mostrando {sectors.length} de {total} registros</div>

		<!-- Infinite Scroll Sentinel -->
		<div bind:this={sentinel} class="h-4 w-full"></div>
	{/if}
</div>
