<script lang="ts">
	import { onMount } from 'svelte';
	import { pedimentosApi, type Pedimento } from '$lib/api/dashboard/a76/pedimentos';
	import DataTable from '$lib/components/dashboard/pedimentos/data-table.svelte';
	import { createColumns } from '$lib/components/dashboard/pedimentos/columns';
	import * as Card from '$lib/components/ui/card';
	import { Button } from '$lib/components/ui/button';
	import { Input } from '$lib/components/ui/input';
	import { Label } from '$lib/components/ui/label';
	import * as Dialog from '$lib/components/ui/dialog';
	import type { PageData } from './$types';
	import { browser } from '$app/environment';
	import { getAccessTokenFromDocument } from '$lib/access-token-cookie-browser';
	import { companyStore } from '$lib/stores/company.svelte';
	import { Edit, Send, Plus, Trash2, RefreshCw } from 'lucide-svelte';
	import { obtenerAtajosListaPedimento } from '$lib/config/shortcuts/dashboard/pedimentos/list';
	import { useShortcuts } from '$lib/hooks/use-shortcuts';
	import { goto } from '$app/navigation';
	import * as AlertDialog from '$lib/components/ui/alert-dialog';
	import { toast } from 'svelte-sonner';
	import { reportsWinsaaiApi } from '$lib/api/dashboard/a76/reports/reports-winsaai';
	import PdfProgressDialog from '$lib/components/dashboard/invoices/pdf-progress-dialog.svelte';
	import { Checkbox } from '$lib/components/ui/checkbox';
	import { get } from 'svelte/store';
	import { currentUser } from '$lib/auth';
	import ErrorState from '$lib/components/dashboard/common/error-state.svelte';
	import {
		canViewPedimentosList,
		canEditPedimento,
		canDeletePedimento,
		canOpenNuevoPedimentoForm
	} from '$lib/permissions/pedimento-permissions';

	// Los datos iniciales vienen del servidor
	let { data }: { data: PageData } = $props();

	const canViewList = $derived(canViewPedimentosList($currentUser));
	const canNuevoPedimentoAction = $derived(canOpenNuevoPedimentoForm($currentUser));
	const canEditPedimentoAction = $derived(canEditPedimento($currentUser));
	const canDeletePedimentoAction = $derived(canDeletePedimento($currentUser));

// Estado para filtros
let filters = $state({
	status: '',
	pedimento: '',
	year: ''
});

	let sorting = $state<import("@tanstack/table-core").SortingState>([{ id: 'id', desc: true }]);

	// Sincronizar token de cookies a localStorage al montar el componente
	onMount(() => {
		if (browser) {
			// Función para obtener el valor de una cookie
			const getCookie = (name: string): string | null => {
				const value = `; ${document.cookie}`;
				const parts = value.split(`; ${name}=`);
				if (parts.length === 2) return parts.pop()?.split(';').shift() || null;
				return null;
			};

			// Verificar si hay token en las cookies
			const cookieToken = getAccessTokenFromDocument();
			const localToken = localStorage.getItem('access_token');

			if (cookieToken && cookieToken !== localToken) {
				localStorage.setItem('access_token', cookieToken);
			}

			// También sincronizar refresh_token si existe
			const cookieRefreshToken = getCookie('refresh_token');
			const localRefreshToken = localStorage.getItem('refresh_token');

			if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) {
				localStorage.setItem('refresh_token', cookieRefreshToken);
			}

			// Escuchar cambios de compañía
			const handleCompanyChange = () => {
				// Recargar los datos sin recargar la página completa
				reloadData();
			};

			window.addEventListener('companyChanged', handleCompanyChange as EventListener);

			// Cleanup
			return () => {
				window.removeEventListener('companyChanged', handleCompanyChange as EventListener);
			};
		}
	});

	// Estado para infinite scroll
	let allItems = $state<Pedimento[]>(data.items || []);
	let currentPage = $state(data.page);
	let pageSize = $state(50);
	let totalItems = $state(data.total || 0);
	let loading = $state(false);
	let isSaving = $state(false);

	// Efecto para reaccionar al cambio de ordenamiento
	$effect(() => {
		if (sorting.length >= 0) {
			applyFilters();
		}
	});
	let hasMore = $derived(allItems.length < totalItems);
	let error = $state<string | null>(data.error || null);

	// Estado para selección de filas
	let selectedId = $state<number | null>(null);
	let showDeleteDialog = $state(false);
	let isWinsaiiConfirmOpen = $state(false);
	let isWinsaiiByClass = $state(false);

	// Estado para diálogos de progreso
	let showProgressDialog = $state(false);
	let progressDialogTitle = $state('Procesando...');
	let currentTaskId = $state<string | null>(null);
	let currentStatusFunction = $state<any>(null);

	let selectedPedimento = $derived(allItems.find((p) => p.id === selectedId) || null);
	const canEditSelected = $derived(
		selectedPedimento ? canEditPedimento($currentUser) : false
	);
	const canDeleteSelected = $derived(
		selectedPedimento ? canDeletePedimento($currentUser) : false
	);

	function handleRowClick(pedimento: Pedimento) {
		// Toggle: si ya está seleccionado, deseleccionar; si no, seleccionar
		selectedId = selectedId === pedimento.id ? null : pedimento.id;
	}

	function handleEditSelected() {
		if (!canEditPedimento(get(currentUser))) {
			toast.error('No tiene permiso para editar pedimentos');
			return;
		}
		if (selectedId) {
			window.location.href = `/dashboard/pedimentos/edit/${selectedId}`;
		}
	}

	function handleDelete() {
		if (!selectedId) {
			return;
		}
		if (!canDeletePedimento(get(currentUser))) {
			toast.error('No tiene permiso para eliminar pedimentos');
			return;
		}
		showDeleteDialog = true;
	}

	async function confirmDelete() {
		if (!selectedId) return;

		const companyId = companyStore.activeCompany?.id;
		if (!companyId) {
			error = 'No hay compañía seleccionada';
			return;
		}

		try {
			const response = await pedimentosApi.delete(selectedId, companyId);

			if (response.error) {
				console.error('🗑️ [Pedimentos] Error al eliminar:', response.error);
				error = response.error;
				return;
			}

			// Recargar datos
			await reloadData();

			selectedId = null;
			showDeleteDialog = false;
		} catch (e) {
			console.error('🗑️ [Pedimentos] Error deleting:', e);
			error = 'Error al eliminar el pedimento';
		}
	}

	function handleInterfaceAgenteAduanal() {
		if (!companyStore.activeCompany) {
			toast.error('No hay empresa seleccionada');
			return;
		}

		if (!selectedPedimento) {
			toast.error('Por favor selecciona un pedimento');
			return;
		}

		// Abrir confirmación
		isWinsaiiConfirmOpen = true;
	}

	async function confirmWinsaiiGeneration() {
		if (!selectedPedimento) return;
		isWinsaiiConfirmOpen = false;

		try {
			const res = await reportsWinsaaiApi.pedimentos.triggerGeneration(
				[selectedPedimento.id],
				true, // isTemporal
				isWinsaiiByClass
			);

			if (res.task_id) {
				currentTaskId = res.task_id;
				currentStatusFunction = reportsWinsaaiApi.pedimentos.getTaskStatus;
				progressDialogTitle = 'Generando Reporte WINSAAI Pedimentos';
				showProgressDialog = true;
			}
		} catch (error) {
			console.error(error);
			toast.error('No se pudo iniciar la generación de Interface Agente Aduanal');
		}
	}

	function onPdfComplete(result: any) {
		try {
			if (result.status === 'success') {
				const blob = base64ToBlob(result.content, result.media_type);
				const url = window.URL.createObjectURL(blob);
				const a = document.createElement('a');
				a.href = url;
				a.download = result.file_name;
				document.body.appendChild(a);
				a.click();
				window.URL.revokeObjectURL(url);
				document.body.removeChild(a);
				toast.success('Archivo descargado exitosamente');
			} else {
				toast.error('Hubo un error en la generación: ' + (result.message || 'Desconocido'));
			}
		} catch (e) {
			console.error('Error al procesar descarga:', e);
			toast.error('Error al procesar el archivo descargado');
		} finally {
			setTimeout(() => {
				showProgressDialog = false;
				currentTaskId = null;
			}, 1000);
		}
	}

	function base64ToBlob(base64: string, type: string) {
		const binStr = atob(base64);
		const len = binStr.length;
		const arr = new Uint8Array(len);
		for (let i = 0; i < len; i++) {
			arr[i] = binStr.charCodeAt(i);
		}
		return new Blob([arr], { type: type });
	}

	// Keyboard Shortcuts
	/** Teclado: foco en la primera fila de datos de la tabla */
	function focusFirstPedimentoTableRow() {
		if (!browser) return;
		const row = document.querySelector<HTMLElement>(
			'[data-pedimento-list-table] tbody tr[data-pedimento-data-row][tabindex="0"]'
		);
		if (row) {
			row.focus();
			setTimeout(() => row.scrollIntoView({ behavior: 'smooth', block: 'nearest' }), 50);
			return;
		}
		toast.info('No hay filas en la tabla');
	}

	/** Teclado: foco en el primer control habilitado de la barra de acciones fija */
	function focusPedimentoListFooterActions() {
		if (!browser) return;
		const footer = document.getElementById('pedimento-list-footer');
		if (!footer) return;
		const candidates = footer.querySelectorAll<HTMLElement>(
			'button, a[href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])'
		);
		for (const el of candidates) {
			if (el.offsetParent === null && el.getClientRects().length === 0) continue;
			if (el.hasAttribute('disabled')) continue;
			if ((el as HTMLButtonElement).disabled) continue;
			el.focus();
			setTimeout(() => el.scrollIntoView({ behavior: 'smooth', block: 'nearest' }), 50);
			return;
		}
		try {
			footer.focus();
		} catch {
			/* ignore */
		}
	}

	async function loadMore() {
		if (loading || !hasMore) return;

		loading = true;
		error = null;

		try {
			const companyId = companyStore.activeCompany?.id;
			if (!companyId) {
				error = 'No hay compañía seleccionada';
				loading = false;
				return;
			}

			const filterParams = {
				status: filters.status || undefined,
				pedimento: filters.pedimento || undefined,
				year: filters.year || undefined,
				sort_by: sorting.length > 0 ? sorting[0].id : undefined,
				sort_order: sorting.length > 0 ? (sorting[0].desc ? 'desc' : 'asc') : undefined
			};

			const response = await pedimentosApi.list(currentPage + 1, pageSize, filterParams, companyId);

			if (response.error) {
				console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status);

				// Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico
				if (response.status === 401 || response.status === 403) {
					error = 'Sesión expirada. Recargando página...';
					// Recargar automáticamente después de 2 segundos
					setTimeout(() => {
						window.location.reload();
					}, 2000);
				} else {
					error = response.error;
				}
				return;
			}

			if (response.data?.items) {
				// Agregar los nuevos items al array existente
				allItems = [...allItems, ...response.data.items];
				currentPage++;
				totalItems = response.data.total;
			}
		} catch (e) {
			error = 'Error cargando más datos';
			console.error('📊 [Page] Error loading more:', e);
		} finally {
			loading = false;
		}
	}

	async function applyFilters() {
		// Reset y recargar con filtros
		loading = true;
		error = null;

		try {
			const companyId = companyStore.activeCompany?.id;
			if (!companyId) {
				error = 'No hay compañía seleccionada';
				loading = false;
				return;
			}

			const filterParams = {
				status: filters.status || undefined,
				pedimento: filters.pedimento || undefined,
				year: filters.year || undefined,
				sort_by: sorting.length > 0 ? sorting[0].id : undefined,
				sort_order: sorting.length > 0 ? (sorting[0].desc ? 'desc' : 'asc') : undefined
			};

			const response = await pedimentosApi.list(1, pageSize, filterParams, companyId);

			if (response.error) {
				console.error('📊 [Page] Error aplicando filtros:', response.error);

				if (response.status === 401 || response.status === 403) {
					error = 'Sesión expirada. Recargando página...';
					setTimeout(() => {
						window.location.reload();
					}, 2000);
				} else {
					error = response.error;
				}
				return;
			}

			if (response.data) {
				allItems = response.data.items;
				currentPage = 1;
				totalItems = response.data.total;
			}
		} catch (e) {
			error = 'Error aplicando filtros';
			console.error('📊 [Page] Error applying filters:', e);
		} finally {
			loading = false;
		}
	}

	function clearFilters() {
		filters = {
			status: '',
			pedimento: '',
			year: ''
		};
		applyFilters();
	}

	async function reloadData() {
		// Reset y recargar desde el principio usando la API
		if (!companyStore.activeCompany) return;

		loading = true;
		error = null;

		try {
			const companyId = companyStore.activeCompany?.id;
			if (!companyId) {
				error = 'No hay compañía seleccionada';
				loading = false;
				return;
			}

			const filterParams = {
				status: filters.status || undefined,
				pedimento: filters.pedimento || undefined,
				year: filters.year || undefined,
				sort_by: sorting.length > 0 ? sorting[0].id : undefined,
				sort_order: sorting.length > 0 ? (sorting[0].desc ? 'desc' : 'asc') : undefined
			};

			const response = await pedimentosApi.list(1, pageSize, filterParams, companyId);

			if (response.error) {
				console.error('📊 [Pedimentos] Error en reloadData:', response.error);
				if (response.status === 401 || response.status === 403) {
					error = 'Sesión expirada. Recargando página...';
					setTimeout(() => {
						window.location.reload();
					}, 2000);
				} else {
					error = response.error;
				}
				return;
			}

			if (response.data?.items) {
				// Reemplazar todos los items con los nuevos datos
				allItems = response.data.items;
				currentPage = 1;
				totalItems = response.data.total;
			}
		} catch (e) {
			error = 'Error recargando datos';
			console.error('📊 [Pedimentos] Error reloading:', e);
		} finally {
			loading = false;
		}
	}

	function handleCreateClick() {
		if (!canOpenNuevoPedimentoForm(get(currentUser))) {
			toast.error('No tiene permiso para crear pedimentos');
			return;
		}
		window.location.href = '/dashboard/pedimentos/edit/new';
	}

	function handleSuccess() {
		// Recargar datos después de crear/editar/eliminar
		reloadData();
	}

	useShortcuts(
		'Pedimentos',
		obtenerAtajosListaPedimento({
			manejarCrear: handleCreateClick,
			manejarActualizar: reloadData,
			manejarEditar: handleEditSelected,
			manejarEliminar: handleDelete,
			irATabla: focusFirstPedimentoTableRow,
			irAAcciones: focusPedimentoListFooterActions
		})
	);

	// Opciones de status para el filtro
	const statusOptions = [
		{ value: '', label: 'Todos' },
		{ value: 'MODIFICABLE', label: 'Modificable' },
		{ value: 'ESPERA FIRMA PREVIO', label: 'Espera de firma previo' },
		{ value: 'ESPERA VALIDACION', label: 'Espera validacion' },
		{ value: 'VALIDADO', label: 'Validado' },
		{ value: 'ESPERA BORRAR FIRMA PREVIO', label: 'Espera borrar firma previo' },
		{ value: 'ESPERA BORRAR FIRMA VALIDACION', label: 'Espera borrar firma validacion ' },
		{ value: 'ESPERA PAGO', label: 'Espera pago' },
		{ value: 'CON FIRMA DE PREVIO', label: 'Con firma de previo' },
		{ value: 'F DE PREVIO BORRADA', label: 'Forma de previo borrada' },
		{ value: 'F VALIDACION BORRADA', label: 'Forma validacion borrada' },
		{ value: 'PAGADO', label: 'Pagado' },
		{ value: 'DESISTIO', label: 'Desistio' },
		{ value: 'ESPERA CARTA CUPO', label: 'Espera carta cupo' },
		{ value: 'CARTA CUPO', label: 'Carta cupo' },
		{ value: 'ESPERA CANCELAR CARTA CUPO', label: 'Espera cancelar carta cupo' }
	];

	// Crear columnas con el callback onSuccess
	const columns = createColumns(handleSuccess);
</script>

{#if !canViewList}
	<div
		class="flex h-[calc(100svh-4rem)] flex-col p-6 group-has-data-[collapsible=icon]/sidebar-wrapper:h-[calc(100svh-3rem)]"
	>
		<ErrorState status={403} />
	</div>
{:else}
<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">
	<!-- Header -->
	<div class="flex items-center justify-between">
		<div>
			<h1 class="text-2xl font-bold tracking-tight">Pedimentos</h1>
			<p class="text-muted-foreground">Gestiona los pedimentos del sistema</p>
		</div>
		<div class="flex flex-wrap items-center gap-2">
			<select
				id="filter-status"
				bind:value={filters.status}
				onchange={applyFilters}
				class="flex h-9 w-[220px] rounded-md border border-input bg-card px-3 py-1 text-sm shadow-sm ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none"
				title="Estado"
			>
				{#each statusOptions as option}
					<option value={option.value}>
						{option.value === '' ? 'Estado: Todos' : option.label}
					</option>
				{/each}
			</select>
			{#if canNuevoPedimentoAction}
				<Button class="h-9" onclick={handleCreateClick}>
					<Plus class="mr-2" size={16} />
					Nuevo Pedimento
				</Button>
			{/if}
		</div>
	</div>

	<!-- Error Message -->
	{#if error}
		<Card.Root class="border-destructive">
			<Card.Header>
				<Card.Title class="text-destructive">Error</Card.Title>
				<Card.Description>{error}</Card.Description>
			</Card.Header>
		</Card.Root>
	{/if}

	<!-- Data Table -->
	<Card.Root class="border bg-background flex flex-col">
		<Card.Header>
			<div class="flex items-center justify-between">
				<div>
					<Card.Title>Listado de Pedimentos</Card.Title>
				</div>
				<div class="flex flex-wrap items-center gap-2">
					<Input
						id="filter-pedimento"
						bind:value={filters.pedimento}
						oninput={applyFilters}
						placeholder="Buscar pedimento"
						class="w-32 lg:w-48 h-9 bg-card"
					/>
					<Input
						id="filter-year"
						bind:value={filters.year}
						oninput={applyFilters}
						placeholder="Año"
						maxlength={2}
						class="w-24 h-9 bg-card"
					/>
					<Button variant="outline" size="sm" class="h-9" onclick={reloadData}>
						<RefreshCw class="mr-2 h-4 w-4" />
						Actualizar
					</Button>
				</div>
			</div>
		</Card.Header>
		<Card.Content class="p-0">
			<!-- TanStack DataTable con Infinite Scroll -->
			<div class="rounded-md border bg-background">
				<DataTable
					data={allItems}
					{columns}
					{loading}
					{hasMore}
					{loadMore}
					{selectedId}
					onRowClick={handleRowClick}
					{sorting}
					onSortingChange={(newSorting) => (sorting = newSorting)}
				/>
			</div>
		</Card.Content>
	</Card.Root>

	<div class="flex-none text-sm text-muted-foreground">
		Mostrando {allItems.length} de {totalItems} registros
		<span class="ml-2">•</span>
		<span class="ml-2">Filtros activos: {Object.values(filters).filter((value) => value !== '').length}</span>
	</div>

	<div class="h-20"></div>

	<!-- Footer fijo con botones de acción -->
	<div
		id="pedimento-list-footer"
		class="fixed right-0 bottom-0 left-0 z-[5] ml-[calc(var(--sidebar-width))] border-t bg-background/95 shadow-lg backdrop-blur group-has-data-[state=collapsed]/sidebar-wrapper:ml-[calc(var(--sidebar-width-icon))] supports-[backdrop-filter]:bg-background/80"
	>
		<div class="mx-auto max-w-[1400px] px-4 py-4">
			<!-- Botones de acción -->
			<div class="flex justify-end gap-2">
				{#if canEditPedimentoAction}
					<Button
						variant="outline"
						size="sm"
						onclick={handleEditSelected}
						disabled={!canEditSelected}
					>
						<Edit size={16} class="mr-1" />
						Editar
					</Button>
				{/if}
				{#if canDeletePedimentoAction}
					<Button
						variant="outline"
						size="sm"
						onclick={handleDelete}
						disabled={!canDeleteSelected}
					>
						<Trash2 size={16} class="mr-1" />
						Borrar
					</Button>
				{/if}
				<Button
					variant="outline"
					size="sm"
					onclick={handleInterfaceAgenteAduanal}
					disabled={!selectedPedimento}
				>
					<Send class="mr-2 h-4 w-4" />
					Interface Agente Aduanal
				</Button>
			</div>
		</div>
	</div>
</div>
{/if}

<!-- Diálogo de confirmación para borrar -->
<Dialog.Root bind:open={showDeleteDialog}>
	<Dialog.Content>
		<Dialog.Header>
			<Dialog.Title>¿Eliminar pedimento?</Dialog.Title>
			<Dialog.Description>
				Esta acción no se puede deshacer. El pedimento será eliminado permanentemente.
			</Dialog.Description>
		</Dialog.Header>
		<div class="mt-4 flex justify-end gap-3">
			<Button variant="outline" onclick={() => (showDeleteDialog = false)}>Cancelar</Button>
			<Button variant="destructive" onclick={confirmDelete}>Eliminar</Button>
		</div>
	</Dialog.Content>
</Dialog.Root>

<AlertDialog.Root bind:open={isWinsaiiConfirmOpen}>
	<AlertDialog.Content>
		<AlertDialog.Header>
			<AlertDialog.Title>¿Generar Interface Agente Aduanal?</AlertDialog.Title>
			<AlertDialog.Description>
				Se generará el reporte WINSAAI para el pedimento seleccionado.
				<div class="mt-4 flex items-center space-x-2">
					<Checkbox id="byClass" bind:checked={isWinsaiiByClass} />
					<Label
						for="byClass"
						class="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
					>
						Agrupar por clase (SCAF)
					</Label>
				</div>
			</AlertDialog.Description>
		</AlertDialog.Header>
		<div class="flex justify-end gap-2">
			<Button variant="outline" onclick={() => (isWinsaiiConfirmOpen = false)}>Cancelar</Button>
			<Button onclick={confirmWinsaiiGeneration}>Generar</Button>
		</div>
	</AlertDialog.Content>
</AlertDialog.Root>

{#if showProgressDialog && currentTaskId}
	<PdfProgressDialog
		bind:open={showProgressDialog}
		taskId={currentTaskId}
		title={progressDialogTitle}
		getStatus={currentStatusFunction}
		onClose={() => (showProgressDialog = false)}
		onComplete={onPdfComplete}
	/>
{/if}
