<script lang="ts">
	import { onMount, tick } from 'svelte';
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import InvoiceDownloadModal from '$lib/components/dashboard/invoices/invoice-download-modal.svelte';
	import TransferenciaElectronicaModal from '$lib/components/dashboard/invoices/transferencia-electronica-modal.svelte';
	import { invoicesApi, type Invoice, type OperationType } from '$lib/api/dashboard/a76/invoices';
	import { invoicesReportsApi } from '$lib/api/dashboard/a76/reports/reports-invoices';
	import { consolidatedReportsApi } from '$lib/api/dashboard/a76/reports/reports-consolidated';
	import { dischargeReportsApi } from '$lib/api/dashboard/a76/reports/reports-descargo';
	import { avisoConsolidadoReportsApi } from '$lib/api/dashboard/a76/reports/reports-aviso-consolidado';
	import { reportsTransmissionApi } from '$lib/api/dashboard/a76/reports/reports-transmission';
	import { reportsWinsaaiApi } from '$lib/api/dashboard/a76/reports/reports-winsaai';
	import DataTable from '$lib/components/dashboard/invoices/data-table.svelte';
	import { createColumns } from '$lib/components/dashboard/invoices/columns';
	import * as Card from '$lib/components/ui/card';
	import * as AlertDialog from '$lib/components/ui/alert-dialog';
	import * as Dialog from '$lib/components/ui/dialog';
	import * as Select from '$lib/components/ui/select';
	import { Button } from '$lib/components/ui/button';
	import { Input } from '$lib/components/ui/input';
	import { Label } from '$lib/components/ui/label';
	import type { PageData } from './$types';
	import { browser } from '$app/environment';
	import { getAccessTokenFromDocument } from '$lib/access-token-cookie-browser';
	import { currentUser } from '$lib/auth';
	import ErrorState from '$lib/components/dashboard/common/error-state.svelte';
	import {
		userCanViewInvoiceListPage,
		userHasInvoiceAction,
		userCanCreateInvoiceForListFilters
	} from '$lib/permissions/invoice-permissions';
	import { companyStore } from '$lib/stores/company.svelte';
	import { getCompany } from '$lib/api/dashboard/a76/general_catalogs/company';
	import { usersAPI } from '$lib/api/dashboard/users';
	import {
		Plus,
		RefreshCw,
		FileText,
		RotateCcw,
		Boxes,
		Package,
		ClipboardList,
		Settings,
		Send,
		Eye,
		Pencil,
		Trash2,
		Download,
		MonitorUp,
		Files,
		ScrollText,
		BadgeCent,
		ArrowRightLeft,
		Database,
		ChevronUp,
		Mail
	} from 'lucide-svelte';
	import DetailsDialog from '$lib/components/dashboard/invoices/details-dialog.svelte';
	import DeleteDialog from '$lib/components/dashboard/invoices/delete-dialog.svelte';
	import * as DropdownMenu from '$lib/components/ui/dropdown-menu';

	// IMPORTANTE: Asegúrate de tener instalada svelte-sonner para las notificaciones
	import { toast } from 'svelte-sonner';
	import { fly } from 'svelte/transition';
	import PdfProgressDialog from '$lib/components/dashboard/invoices/pdf-progress-dialog.svelte';
	import { useShortcuts } from '$lib/hooks/use-shortcuts';
	import { obtenerAtajosListaFacturas } from '$lib/config/shortcuts/dashboard/invoices/list';
	import { m } from '$lib/i18n/messages';
	import { humanizeLineReferences } from '$lib/api';

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

	type CoveRecipientOption = {
		email: string;
		label: string;
		description: string;
		source: 'company' | 'user';
	};

	// Estado para filtros
	// Nota: Los query parameters invoice_type y operation_type se pueden usar para filtrar
	// Ejemplo: /dashboard/invoices?invoice_type=TEM&operation_type=imp
	let filters = $state({
		operation_type: (data.filters?.operation_type || '') as '' | OperationType,
		invoice_type: data.filters?.invoice_type || '',
		invoice_number: data.filters?.invoice_number || '',
		year_from: data.filters?.year || '',
		year_to: data.filters?.year || ''
	});
	
	let sorting = $state<import("@tanstack/table-core").SortingState>([]);

	let isDownloadModalOpen = $state(false);
	let isTransferenciaModalOpen = $state(false);
	let isRevertConfirmOpen = $state(false);

	// Efecto reactivo para actualizar filtros cuando cambian los query parameters en la URL
	$effect(() => {
		if (browser) {
			const searchParams = $page.url.searchParams;
			const urlOperationType = searchParams.get('operation_type');
			const urlInvoiceType = searchParams.get('invoice_type');
			const urlInvoiceNumber = searchParams.get('invoice_number');
			const urlYearFrom = searchParams.get('year_from');
			const urlYearTo = searchParams.get('year_to');

			// Actualizar filtros si hay cambios en la URL
			filters.operation_type = (urlOperationType || '') as '' | OperationType;
			filters.invoice_type = urlInvoiceType || '';
			filters.invoice_number = urlInvoiceNumber || '';
			filters.year_from = urlYearFrom || '';
			filters.year_to = urlYearTo || '';
		}
	});

	// Efecto para limpiar invoice_type si no es válido para el operation_type seleccionado
	$effect(() => {
		if (filters.invoice_type && filters.operation_type) {
			const selectedOption = allInvoiceTypeOptions().find(
				(opt) => opt.value === filters.invoice_type
			);
			if (
				selectedOption &&
				selectedOption.operation !== 'both' &&
				selectedOption.operation !== filters.operation_type
			) {
				// El tipo de factura seleccionado no es válido para esta operación
				filters.invoice_type = '';
			}
		}
	});

	// Efecto para actualizar la URL cuando cambien los filtros
	$effect(() => {
		if (browser) {
			const params = new URLSearchParams();

			if (filters.operation_type) params.set('operation_type', filters.operation_type);
			if (filters.invoice_type) params.set('invoice_type', filters.invoice_type);
			if (filters.invoice_number) params.set('invoice_number', filters.invoice_number);
			if (filters.year_from) params.set('year_from', filters.year_from);
			if (filters.year_to) params.set('year_to', filters.year_to);

			const queryString = params.toString();
			const newUrl = queryString ? `?${queryString}` : window.location.pathname;

			// Solo actualizar si la URL es diferente (evitar loops infinitos)
			if (window.location.search !== (queryString ? `?${queryString}` : '')) {
				window.history.replaceState({}, '', newUrl);
			}
		}
	});

	// Efecto para aplicar filtros automáticamente cuando cambian
	let filterTimeout: ReturnType<typeof setTimeout> | null = null;
	let lastFiltersKey = '';
	$effect(() => {
		// Observar cambios en los filtros
		const currentFilters = {
			operation_type: filters.operation_type,
			invoice_type: filters.invoice_type,
			invoice_number: filters.invoice_number,
			year_from: filters.year_from,
			year_to: filters.year_to
		};
		const currentFiltersKey = JSON.stringify(currentFilters);

		// Limpiar selección cada vez que se modifica algún filtro o el orden
		if (currentFiltersKey !== lastFiltersKey) {
			selectedInvoiceIds = [];
			lastFiltersKey = currentFiltersKey;
		}

		// Debounce para evitar múltiples llamadas rápidas
		if (filterTimeout) clearTimeout(filterTimeout);
		filterTimeout = setTimeout(() => {
			applyFilters();
		}, 300); // Esperar 300ms después del último cambio
	});

	// Efecto para reaccionar al cambio de ordenamiento
	$effect(() => {
		// Cuando cambia el sorting, aplicamos filtros (que reinicia a la página 1)
		if (sorting.length >= 0) {
			applyFilters();
		}
	});

	// 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 = (event: CustomEvent) => {
				// 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<Invoice[]>(data.items || []);
	let currentPage = $state(data.page);
	let pageSize = $state(50);
	let totalItems = $state(data.total || 0);
	let loading = $state(false);
	let hasMore = $derived(allItems.length < totalItems);
	let error = $state<string | null>(data.error || null);

	// Estado para selección de filas (múltiple)
	let selectedInvoiceIds = $state<number[]>([]);
	// Estado para los diálogos de acciones
	let showDetailsDialog = $state(false);
	let showDeleteDialog = $state(false);
	let reportesMenuOpen = $state(false);
	let masAccionesMenuOpen = $state(false);

	$effect(() => {
		if (reportesMenuOpen) masAccionesMenuOpen = false;
	});
	$effect(() => {
		if (masAccionesMenuOpen) reportesMenuOpen = false;
	});

	function handleRowClick(invoice: Invoice) {
		const id = invoice.id;
		if (selectedInvoiceIds.includes(id)) {
			// Deseleccionar si ya estaba
			selectedInvoiceIds = selectedInvoiceIds.filter((selectedId) => selectedId !== id);
		} else {
			// Seleccionar agregando a la lista
			selectedInvoiceIds = [...selectedInvoiceIds, id];
		}
	}

	const selectedInvoice = $derived(
		selectedInvoiceIds.length === 1 ? allItems.find((i) => i.id === selectedInvoiceIds[0]) : null
	);

	const hasSelection = $derived(selectedInvoiceIds.length > 0);

	const canViewInvoiceSection = $derived(
		userCanViewInvoiceListPage(
			$currentUser,
			filters.operation_type,
			filters.invoice_type
		)
	);

	const canCreateInvoice = $derived(
		userCanCreateInvoiceForListFilters(
			$currentUser,
			filters.operation_type,
			filters.invoice_type
		)
	);

	const canEditSelected = $derived(
		selectedInvoice
			? userHasInvoiceAction(
					$currentUser,
					String(selectedInvoice.operation_type),
					String(selectedInvoice.invoice_type),
					'edit'
				)
			: false
	);

	const canDeleteSelection = $derived.by(() => {
		if (selectedInvoiceIds.length === 0) return false;
		const items = selectedInvoiceIds
			.map((id) => allItems.find((i) => i.id === id))
			.filter((i): i is Invoice => i !== undefined);
		if (items.length !== selectedInvoiceIds.length) return false;
		return items.every((inv) =>
			userHasInvoiceAction(
				$currentUser,
				String(inv.operation_type),
				String(inv.invoice_type),
				'delete'
			)
		);
	});

	const canProcessSelected = $derived(
		selectedInvoice
			? userHasInvoiceAction(
					$currentUser,
					String(selectedInvoice.operation_type),
					String(selectedInvoice.invoice_type),
					'process'
				)
			: false
	);

	const canViewSelected = $derived(
		selectedInvoice
			? userHasInvoiceAction(
					$currentUser,
					String(selectedInvoice.operation_type),
					String(selectedInvoice.invoice_type),
					'view'
				)
			: false
	);

	// Submenú contextual para Interface VU (click derecho); overlay conservado para trabajo futuro
	let showVuSubmenu = $state(false);
	let vuSubmenuPosition = $state({ x: 0, y: 0 });

	$effect(() => {
		if (!hasSelection) {
			showVuSubmenu = false;
		}
	});

	// Título dinámico según el tipo de operación y tipo de factura (i18n para casos clásicos; catálogo API para el resto)
	const viewTitle = $derived.by(() => {
		const op = filters.operation_type;
		const type = (filters.invoice_type || '').trim();

		const base = m['invoice_list.titles.base']();

		const titleFromInvoiceTypesCatalog = (): string | null => {
			if (!type || !data.invoiceTypes?.length) return null;
			const hit = data.invoiceTypes.find((t: { key: string }) => t.key === type);
			if (!hit?.description) return null;
			return `${base} DE ${String(hit.description).trim().toUpperCase()}`;
		};

		if (op === 'imp') {
			if (type === 'TEM') return `${base} ${m['invoice_list.titles.import_temporal']()}`;
			if (type === 'DEF') return `${base} ${m['invoice_list.titles.import_definitive']()}`;
			if (type === 'MEX') return `${base} ${m['invoice_list.titles.import_mexican']()}`;
			if (type === 'CR') return `${base} ${m['invoice_list.titles.import_regime_change']()}`;
			if (type === 'REP') return `${base} ${m['invoice_list.titles.import_repair']()}`;
			const catalogTitle = titleFromInvoiceTypesCatalog();
			if (catalogTitle) return catalogTitle;
			return `${base} ${m['invoice_list.titles.import']()}`;
		}

		if (op === 'exp') {
			if (type === 'EXDEF') return `${base} ${m['invoice_list.titles.export_definitive']()}`;
			if (type === 'REPAR') return `${base} ${m['invoice_list.titles.export_repair']()}`;
			const catalogTitle = titleFromInvoiceTypesCatalog();
			if (catalogTitle) return catalogTitle;
			return `${base} ${m['invoice_list.titles.export']()}`;
		}

		return m['invoice_list.header.title']();
	});

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

		loading = true;
		error = null;

		try {
			const companyId = companyStore.activeCompany?.id;
			if (!companyId) {
				error = m.invoice_list_toasts_no_company_selected();
				return;
			}

			const filterParams = {
				operation_type: filters.operation_type || undefined,
				invoice_type: filters.invoice_type || undefined,
				invoice_number: filters.invoice_number || undefined,
				year_from: filters.year_from || undefined,
				year_to: filters.year_to || undefined,
				sort_by: sorting.length > 0 ? sorting[0].id : undefined,
				sort_order: sorting.length > 0 ? (sorting[0].desc ? 'desc' : 'asc') : undefined
			};

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

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

				if (response.status === 401 || response.status === 403) {
					error = m.invoice_list_toasts_session_expired_reloading();
					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 = m.invoice_list_toasts_load_more_error();
			console.error('📊 [Invoices] 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 = m.invoice_list_toasts_no_company_selected();
				return;
			}

			// Construir query parameters para el endpoint
			// Los filtros se mapean a los parámetros del API
			const filterParams = {
				operation_type: filters.operation_type || undefined,
				invoice_type: filters.invoice_type || undefined,
				invoice_number: filters.invoice_number || undefined,
				year_from: filters.year_from || undefined,
				year_to: filters.year_to || undefined,
				sort_by: sorting.length > 0 ? sorting[0].id : undefined,
				sort_order: sorting.length > 0 ? (sorting[0].desc ? 'desc' : 'asc') : undefined
			};

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

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

				if (response.status === 401 || response.status === 403) {
					error = m.invoice_list_toasts_session_expired_reloading();
					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 = m.invoice_list_toasts_apply_filters_error();
			console.error('📊 [Invoices] Error applying filters:', e);
		} finally {
			loading = false;
		}
	}

	function clearFilters() {
		filters = {
			operation_type: '',
			invoice_type: '',
			invoice_number: '',
			year_from: '',
			year_to: ''
		};
		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;

			const filterParams = {
				operation_type: filters.operation_type || undefined,
				invoice_type: filters.invoice_type || undefined,
				invoice_number: filters.invoice_number || undefined,
				year_from: filters.year_from || undefined,
				year_to: filters.year_to || undefined,
				sort_by: sorting.length > 0 ? sorting[0].id : undefined,
				sort_order: sorting.length > 0 ? (sorting[0].desc ? 'desc' : 'asc') : undefined
			};

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

			if (response.error) {
				console.error('📊 [Invoices] 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 = m.invoice_list_toasts_reload_data_error();
			console.error('📊 [Invoices] Error reloading:', e);
		} finally {
			loading = false;
		}
	}

	// Estado para el diálogo de progreso
	let showProgressDialog = $state(false);
	let isWinsaiiConfirmOpen = $state(false);
	let isCoveDialogOpen = $state(false);
	let currentTaskId = $state<string | null>(null);
	let currentStatusFunction = $state<((taskId: string) => Promise<any>) | null>(null);
	let progressDialogTitle = $state('Generando documento');
	let progressDialogSteps = $state<{ label: string; percent: number }[] | null>(null);
	let isProgressErrorOpen = $state(false);
	let progressErrorTitle = $state('Ocurrió un error');
	let progressErrorDescription = $state('No se pudo completar la acción.');
	let coveRecipientsLoading = $state(false);
	let coveRecipientsError = $state<string | null>(null);
	let coveRecipientEmail = $state('');
	let coveRecipientOptions = $state<CoveRecipientOption[]>([]);
	let coveRecipientsRequestId = 0;

	const currentUserEmail = $derived(($currentUser?.email || '').trim());
	const selectedCoveRecipient = $derived(
		coveRecipientOptions.find(
			(option) => option.email.trim().toLowerCase() === coveRecipientEmail.trim().toLowerCase()
		) ?? null
	);

	function normalizeEmail(email?: string | null) {
		return (email || '').trim().toLowerCase();
	}

	async function loadCoveRecipients() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) {
			coveRecipientsError = null;
			coveRecipientOptions = [];
			coveRecipientEmail = '';
			return;
		}

		const requestId = ++coveRecipientsRequestId;
		coveRecipientsLoading = true;
		coveRecipientsError = null;

		try {
			const [companyResult, usersResult] = await Promise.allSettled([
				getCompany(companyId),
				usersAPI.list(companyId, { page_size: 100 })
			]);

			if (requestId !== coveRecipientsRequestId) return;

			const recipientMap = new Map<string, CoveRecipientOption>();

			const addRecipient = (
				email?: string | null,
				label?: string,
				description?: string,
				source: 'company' | 'user' = 'user'
			) => {
				const normalizedEmail = normalizeEmail(email);
				if (!normalizedEmail) return;
				if (recipientMap.has(normalizedEmail)) return;
				recipientMap.set(normalizedEmail, {
					email: email!.trim(),
					label: label || email!.trim(),
					description: description || email!.trim(),
					source
				});
			};

			if (companyResult.status === 'fulfilled' && companyResult.value.data) {
				const company = companyResult.value.data as Record<string, any>;
				addRecipient(
					company.vu_email,
					m.invoice_list_recipients_company_vu_email(),
					company.name
						? m.invoice_list_recipients_company_description({ name: company.name })
						: m.invoice_list_recipients_single_window_email(),
					'company'
				);
				addRecipient(
					company.main_email,
					m.invoice_list_recipients_company_main_email(),
					company.name
						? m.invoice_list_recipients_company_description({ name: company.name })
						: m.invoice_list_recipients_main_email(),
					'company'
				);
				addRecipient(
					company.ind1_email,
					m.invoice_list_recipients_company_industrial_1(),
					company.name
						? m.invoice_list_recipients_company_description({ name: company.name })
						: m.invoice_list_recipients_company_industrial_1(),
					'company'
				);
				addRecipient(
					company.ind2_email,
					m.invoice_list_recipients_company_industrial_2(),
					company.name
						? m.invoice_list_recipients_company_description({ name: company.name })
						: m.invoice_list_recipients_company_industrial_2(),
					'company'
				);
			}

			if (usersResult.status === 'fulfilled' && usersResult.value.users) {
				for (const user of usersResult.value.users) {
					const fullName = `${user.first_name || ''} ${user.last_name || ''}`.trim();
					addRecipient(
						user.email,
						fullName || user.username || user.email,
						m.invoice_list_recipients_company_user_email({ email: user.email }),
						'user'
					);
				}
			}

			if (currentUserEmail) {
				addRecipient(
					currentUserEmail,
					m.invoice_list_recipients_my_email(),
					m.invoice_list_recipients_authenticated_user({ email: currentUserEmail }),
					'user'
				);
			}

			const recipients = [...recipientMap.values()].sort((left, right) => {
				if (left.source !== right.source) {
					return left.source === 'company' ? -1 : 1;
				}
				return left.label.localeCompare(right.label, 'es');
			});

			const sourceFailures = [companyResult, usersResult].filter(
				(result) => result.status === 'rejected'
			).length;

			coveRecipientOptions = recipients;

			const preferredEmail = normalizeEmail(currentUserEmail);
			const existingSelection =
				recipients.find((option) => normalizeEmail(option.email) === normalizeEmail(coveRecipientEmail)) ||
				null;
			const preferredSelection =
				recipients.find((option) => normalizeEmail(option.email) === preferredEmail) || recipients[0] || null;

			if (existingSelection) {
				coveRecipientEmail = existingSelection.email;
			} else if (preferredSelection) {
				coveRecipientEmail = preferredSelection.email;
			} else {
				coveRecipientEmail = '';
			}

			if (recipientMap.size === 0 && sourceFailures > 0) {
				coveRecipientsError = m.invoice_list_recipients_load_error();
			} else if (recipientMap.size === 0) {
				coveRecipientsError = m.invoice_list_recipients_no_configured();
			}
		} catch (error) {
			if (requestId !== coveRecipientsRequestId) return;
			console.error('Error cargando correos de COVE:', error);
			coveRecipientsError = m.invoice_list_recipients_load_error();
		} finally {
			if (requestId === coveRecipientsRequestId) {
				coveRecipientsLoading = false;
			}
		}
	}

	$effect(() => {
		const companyId = companyStore.activeCompany?.id;
		const userEmail = currentUserEmail;

		if (!companyId) {
			coveRecipientsError = null;
			coveRecipientOptions = [];
			coveRecipientEmail = '';
			return;
		}

		void userEmail;
		void loadCoveRecipients();
	});

	function openCoveDialog() {
		if (!selectedInvoice || !companyStore.activeCompany) {
			toast.info(m.invoice_list_toasts_select_invoice_for_cove());
			return;
		}

		void loadCoveRecipients();
		isCoveDialogOpen = true;
	}

	// Utilidad para convertir Base64 a Blob
	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 });
	}

	async function handleDownloadPdf(invoice: any) {
		if (!companyStore.activeCompany) {
			toast.error(m.invoice_list_toasts_no_company_selected());
			return;
		}

		try {
			// 1. Trigger: Iniciar la tarea en Celery
			const { task_id } = await invoicesReportsApi.triggerPdfGeneration(
				invoice.id,
				companyStore.activeCompany.id
			);

			// 2. Abrir diálogo de progreso
			currentTaskId = task_id;
			currentStatusFunction = invoicesReportsApi.getTaskStatus;
			progressDialogTitle = m.invoice_list_progress_title_pdf();
			showProgressDialog = true;
		} catch (error: any) {
			console.error(error);
			toast.error(error.message || m.invoice_list_toasts_download_start_error());
		}
	}

	async function handleDownloadConsolidated(invoice: any) {
		if (!companyStore.activeCompany) {
			toast.error(m.invoice_list_toasts_no_company_selected());
			return;
		}

		try {
			// 1. Trigger: Iniciar la tarea en Celery (Consolidado Importación)
			const { task_id } = await consolidatedReportsApi.triggerPdfGeneration(
				invoice.id,
				companyStore.activeCompany.id
			);

			// 2. Abrir diálogo de progreso
			currentTaskId = task_id;
			currentStatusFunction = consolidatedReportsApi.getTaskStatus;
			progressDialogTitle = m.invoice_list_progress_title_consolidated();
			showProgressDialog = true;
		} catch (error) {
			console.error(error);
			toast.error(m.invoice_list_toasts_consolidated_download_start_error());
		}
	}

	async function handleDownloadDescargo(invoice: any) {
		if (!companyStore.activeCompany) {
			toast.error(m.invoice_list_toasts_no_company_selected());
			return;
		}

		try {
			// 0. Trigger: Ejecutar Asignación PEPS (FIFO)
			toast.info(m.invoice_list_toasts_calculating_peps());
			const fifoResponse = await dischargeReportsApi.assignFifo(invoice.id);

			if (fifoResponse.error) {
				toast.error(
					m.invoice_list_toasts_peps_calculation_error_prefix({
						error: String(fifoResponse.error)
					})
				);
				return;
			}
			toast.success(m.invoice_list_toasts_peps_calculation_completed());

			// 1. Trigger: Iniciar la tarea en Celery
			const { task_id } = await dischargeReportsApi.triggerPdfGeneration(
				invoice.id,
				companyStore.activeCompany.id
			);

			// 2. Abrir diálogo de progreso
			currentTaskId = task_id;
			currentStatusFunction = dischargeReportsApi.getTaskStatus;
			progressDialogTitle = m.invoice_list_progress_title_descargo();
			showProgressDialog = true;
		} catch (error) {
			console.error(error);
			toast.error(m.invoice_list_toasts_peps_report_start_error());
		}
	}

	async function handleDownloadAvisoConsolidado(invoice: any) {
		if (!companyStore.activeCompany) {
			toast.error(m.invoice_list_toasts_no_company_selected());
			return;
		}

		try {
			// 1. Trigger: Iniciar la tarea en Celery (Aviso Consolidado Exportación)
			const { task_id } = await avisoConsolidadoReportsApi.triggerPdfGeneration(
				invoice.id,
				companyStore.activeCompany.id
			);

			// 2. Abrir diálogo de progreso
			currentTaskId = task_id;
			currentStatusFunction = avisoConsolidadoReportsApi.getTaskStatus;
			progressDialogTitle = m.invoice_list_progress_title_consolidated();
			showProgressDialog = true;
		} catch (error) {
			console.error(error);
			toast.error(m.invoice_list_toasts_aviso_consolidado_start_error());
		}
	}

	async function handleDownloadPackingList(invoice: any) {
		if (!companyStore.activeCompany) {
			toast.error(m.invoice_list_toasts_no_company_selected());
			return;
		}

		try {
			// 1. Trigger: Start task in Celery
			const { task_id } = await invoicesReportsApi.triggerPackingListGeneration(
				invoice.id,
				companyStore.activeCompany.id
			);

			// 2. Open progress dialog
			currentTaskId = task_id;
			// Use the specific status function for Packing List
			currentStatusFunction = invoicesReportsApi.getPackingListTaskStatus;
			progressDialogTitle = m.invoice_list_progress_title_packing_list();
			showProgressDialog = true;
		} catch (error) {
			console.error(error);
			toast.error(m.invoice_list_toasts_packing_list_start_error());
		}
	}

	async function handleInterfaceAgenteAduanal(invoice: any) {
		if (!companyStore.activeCompany) {
			toast.error(m.invoice_list_toasts_no_company_selected());
			return;
		}

		if (invoice.operation_type !== 'imp') {
			toast.info(m.invoice_list_toasts_fast_interface_import_only());
			return;
		}

		// Abrir confirmación
		isWinsaiiConfirmOpen = true;
	}

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

		try {
			const res = await reportsWinsaaiApi.invoices.triggerGeneration({
				invoice_ids: [selectedInvoice.id],
				is_temporal: selectedInvoice.invoice_type === 'TEM'
			});

			if (res.task_id) {
				currentTaskId = res.task_id;
				// Use the specific status and download functions for WINSAAI
				currentStatusFunction = reportsWinsaaiApi.invoices.getTaskStatus;
				progressDialogTitle = m.invoice_list_progress_title_winsaai();
				showProgressDialog = true;
			}
		} catch (error) {
			console.error(error);
			toast.error(m.invoice_list_toasts_customs_broker_interface_start_error());
		}
	}

	function onPdfComplete(result: any) {
		try {
			if (result.status === 'success') {
				if (result.content) {
					// Resultado de generación de PDF: descargar archivo
					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(m.invoice_list_toasts_pdf_download_success());
				} else if (result.cove_number) {
					// Resultado de generación de COVE
					const baseMsg = `COVE generado correctamente: ${result.cove_number}`;
					const opMsg = result.vucem_operation_num
						? ` (Operación VUCEM: ${result.vucem_operation_num})`
						: '';
					toast.success(baseMsg + opMsg);
					reloadData();
				} else {
					// Resultado de procesamiento de factura (import process/revert)
					toast.success(m.invoice_list_toasts_invoice_processed_success());
					reloadData();
				}
			} else if (result.status === 'external_queued') {
				// Caso especial: VU aceptó la factura y la dejó en cola, pero devuelve
				// un mensaje tipo "Factura COVE iniciada para: ... Use el task_id para consultar el estado."
				const baseMsg =
					result.message ||
					m.invoice_list_toasts_cove_external_queued_default();
				const taskInfo = result.external_task_id ? ` (task_id: ${result.external_task_id})` : '';
				toast.success(baseMsg + taskInfo);
			} else if (result.status === 'validation_error' || result.status === 'error') {
				// El diálogo de progreso ya muestra `result.errors` detallados; reforzamos con toast breve.
				const errs = Array.isArray(result.errors) ? result.errors : [];
				if (errs.length > 0) {
					const first = errs[0];
					const line =
						typeof first?.message === 'string'
							? first.message
							: String(first?.message ?? '');
					const more =
						errs.length > 1 ? ` (+${errs.length - 1} más — revisa el cuadro de diálogo)` : '';
					toast.error(`${line}${more}`);
				} else if (typeof result.message === 'string' && result.message.trim()) {
					toast.error(result.message.trim());
				}
				reloadData();
				return;
			} else if (
				typeof result.message === 'string' &&
				result.message.includes('Factura COVE iniciada para')
			) {
				// Salvaguarda: si por alguna razón el status no vino como external_queued
				// pero el mensaje es el de "Factura COVE iniciada...", lo tratamos también
				// como éxito/en cola y no como error.
				const taskInfo = result.external_task_id ? ` (task_id: ${result.external_task_id})` : '';
				toast.success(result.message + taskInfo);
			} else {
				const resolvedError =
					(typeof result === 'string' && result.trim()) ||
					(typeof result?.message === 'string' && result.message.trim()) ||
					(typeof result?.error === 'string' && result.error.trim()) ||
					(typeof result?.detail === 'string' && result.detail.trim()) ||
					(typeof result?.result === 'string' && result.result.trim()) ||
					(Array.isArray(result?.errors) &&
						typeof result.errors[0]?.message === 'string' &&
						result.errors[0].message.trim()) ||
					m.invoice_table_not_available_short();
				toast.error(
					m.invoice_list_toasts_worker_error_prefix({
						error: String(resolvedError)
					})
				);
			}
		} catch (e) {
			console.error('Error al procesar resultado:', e);
			toast.error(m.invoice_list_toasts_task_result_process_error());
		}
	}

	function handleCreateClick() {
		if (!canCreateInvoice) {
			toast.error('No tienes permiso para crear este tipo de factura.');
			return;
		}

		const params = new URLSearchParams(window.location.search);

		const queryString = params.toString();
		const url = queryString
			? `/dashboard/invoices/edit/new?${queryString}`
			: '/dashboard/invoices/edit/new';

		window.location.href = url;
	}

	function handleEditSelected() {
		if (selectedInvoice) {
			const params = new URLSearchParams(window.location.search);
			const queryString = params.toString();
			const url = queryString
				? `/dashboard/invoices/edit/${selectedInvoice.id}?${queryString}`
				: `/dashboard/invoices/edit/${selectedInvoice.id}`;
			window.location.href = url;
		} else {
			toast.info(m.invoice_list_toasts_select_invoice_to_edit());
		}
	}

	/** Teclado: foco en la primera fila de datos del listado */
	function focusFirstInvoiceTableRow() {
		if (!browser) return;
		const row = document.querySelector<HTMLElement>(
			'[data-invoice-list-table] tbody tr[data-invoice-data-row][tabindex="0"]'
		);
		if (row) {
			row.focus();
			setTimeout(() => row.scrollIntoView({ behavior: 'smooth', block: 'nearest' }), 50);
			return;
		}
		toast.info(m.invoice_list_toasts_no_table_rows());
	}

	/** Teclado: foco en el primer control habilitado de la barra de acciones fija */
	function focusInvoiceListFooterActions() {
		if (!browser) return;
		const footer = document.getElementById('invoice-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 */
		}
	}

	function getInvoiceFooterToolbarButtons(): HTMLButtonElement[] {
		const toolbar = document.querySelector('#invoice-list-footer [data-invoice-footer-toolbar]');
		if (!toolbar) return [];
		return Array.from(toolbar.querySelectorAll<HTMLButtonElement>('[data-footer-action]'));
	}

	async function focusFirstItemInFooterDropdown(kind: 'reportes' | 'mas-acciones') {
		await tick();
		requestAnimationFrame(() => {
			requestAnimationFrame(() => {
				const menu = document.querySelector(`[data-invoice-footer-dropdown="${kind}"]`);
				const item = menu?.querySelector(
					'[data-slot="dropdown-menu-item"]:not([data-disabled])'
				) as HTMLElement | null;
				item?.focus();
			});
		});
	}

	function openReportesMenuFromShortcut() {
		if (selectedInvoiceIds.length !== 1) {
			toast.info(m.invoice_list_toasts_select_invoice_for_reports());
			return;
		}
		reportesMenuOpen = true;
		void focusFirstItemInFooterDropdown('reportes');
	}

	function openMasAccionesMenuFromShortcut() {
		if (selectedInvoiceIds.length !== 1) {
			toast.info(m.invoice_list_toasts_select_invoice_for_more_actions());
			return;
		}
		masAccionesMenuOpen = true;
		void focusFirstItemInFooterDropdown('mas-acciones');
	}

	function footerProcesarFactura() {
		void handleProcessInvoice();
	}

	function footerDesactualizar() {
		if (selectedInvoiceIds.length !== 1) {
			toast.info(m.invoice_list_toasts_select_invoice_to_revert());
			return;
		}
		isRevertConfirmOpen = true;
	}

	function footerVerDetalles() {
		if (selectedInvoiceIds.length !== 1) {
			toast.info(m.invoice_list_toasts_select_invoice_for_details());
			return;
		}
		showDetailsDialog = true;
	}

	function footerInterfaceAgenteAduanal() {
		if (!selectedInvoice) {
			toast.info(m.invoice_list_toasts_select_invoice());
			return;
		}
		void handleInterfaceAgenteAduanal(selectedInvoice);
	}

	function footerEliminar() {
		if (selectedInvoiceIds.length === 0) {
			toast.info(m.invoice_list_toasts_select_at_least_one_invoice_to_delete());
			return;
		}
		showDeleteDialog = true;
	}

	function handleInvoiceFooterToolbarKeydown(event: KeyboardEvent) {
		if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return;
		const target = event.target as HTMLElement | null;
		if (!target?.closest('[data-invoice-footer-toolbar]')) return;
		if (target.closest('[data-slot="dropdown-menu-content"]')) return;

		const buttons = getInvoiceFooterToolbarButtons().filter((b) => !b.disabled);
		if (buttons.length === 0) return;
		const active = document.activeElement as HTMLButtonElement | null;
		let idx = active ? buttons.indexOf(active) : -1;
		if (idx === -1) {
			idx = event.key === 'ArrowRight' ? 0 : buttons.length - 1;
		} else if (event.key === 'ArrowRight') {
			idx = (idx + 1) % buttons.length;
		} else {
			idx = (idx - 1 + buttons.length) % buttons.length;
		}
		event.preventDefault();
		buttons[idx]?.focus();
	}

	useShortcuts(
		'Invoices List',
		obtenerAtajosListaFacturas({
			manejarCrear: handleCreateClick,
			manejarActualizar: reloadData,
			manejarEditar: handleEditSelected,
			manejarDescargarPdf: () => {
				if (selectedInvoice) handleDownloadPdf(selectedInvoice);
				else toast.info(m.invoice_list_toasts_select_invoice_for_pdf());
			},
			manejarDescargarConsolidado: () => {
				if (selectedInvoice) handleDownloadConsolidated(selectedInvoice);
				else toast.info(m.invoice_list_toasts_select_invoice_for_consolidated());
			},
			irTemporal: () => goto('/dashboard/invoices?operation_type=imp&invoice_type=TEM'),
			irDefinitiva: () => goto('/dashboard/invoices?operation_type=imp&invoice_type=DEF'),
			irNacional: () => goto('/dashboard/invoices?operation_type=imp&invoice_type=MEX'),
			irCambioRegimen: () => goto('/dashboard/invoices?operation_type=imp&invoice_type=CR'),
			irExportacion: () => goto('/dashboard/invoices?operation_type=exp'),
			irReparacion: () => goto('/dashboard/invoices?operation_type=exp&invoice_type=REPAR'),
			irATabla: focusFirstInvoiceTableRow,
			irAAcciones: focusInvoiceListFooterActions,
			abrirMenuReportes: openReportesMenuFromShortcut,
			abrirMenuMasAcciones: openMasAccionesMenuFromShortcut,
			footerProcesar: footerProcesarFactura,
			footerDesactualizar,
			footerVerDetalles,
			footerInterfaceAgenteAduanal,
			footerEliminar
		})
	);

	function handleSuccess() {
		reloadData();
	}

	async function handleUpdateStatus(status: boolean) {
		if (!selectedInvoice || !companyStore.activeCompany) {
			toast.info(m.invoice_list_toasts_select_invoice_to_change_status());
			return;
		}

		loading = true;
		try {
			const companyId = companyStore.activeCompany.id;
			const response = await invoicesApi.update(selectedInvoice.id, companyId, {
				id: selectedInvoice.id,
				status: status
			});

			if (response.error) {
				toast.error(
					m.invoice_list_toasts_update_status_error_prefix({
						action: status
							? m.invoice_list_toasts_status_action_update()
							: m.invoice_list_toasts_status_action_revert(),
						error: String(response.error)
					})
				);
			} else {
				toast.success(
					status
						? m.invoice_list_toasts_status_updated_success()
						: m.invoice_list_toasts_status_reverted_success()
				);
				reloadData();
			}
		} catch (e) {
			console.error('Error updating status:', e);
			toast.error(m.invoice_list_toasts_update_status_unexpected_error());
		} finally {
			loading = false;
		}
	}

	async function handleProcessInvoice() {
		if (!selectedInvoice || !companyStore.activeCompany) {
			toast.info(m.invoice_list_toasts_select_invoice_to_process());
			return;
		}

		try {
			const response = await invoicesApi.processInvoice(
				selectedInvoice.id,
				companyStore.activeCompany.id
			);

			if (response.error) {
				openProgressErrorDialog(
					'No se pudo iniciar el procesamiento de la factura',
					m.invoice_list_toasts_process_start_error_prefix({ error: String(response.error) })
				);
				return;
			}

			currentTaskId = response.data!.task_id;
			currentStatusFunction = invoicesApi.getProcessStatus;
			progressDialogTitle = m.invoice_list_progress_title_process_invoice();
			progressDialogSteps = invoiceProcessSteps;
			showProgressDialog = true;
		} catch (e) {
			console.error('Error al iniciar proceso de factura:', e);
			openProgressErrorDialog(
				'No se pudo iniciar el procesamiento de la factura',
				m.invoice_list_toasts_process_start_error()
			);
		}
	}

	async function confirmRevertInvoice() {
		if (!selectedInvoice || !companyStore.activeCompany) return;
		isRevertConfirmOpen = false;

		try {
			const response = await invoicesApi.revertInvoice(
				selectedInvoice.id,
				companyStore.activeCompany.id
			);

			if (response.error) {
				openProgressErrorDialog(
					'No se pudo iniciar la desactualización de la factura',
					m.invoice_list_toasts_revert_start_error_prefix({ error: String(response.error) })
				);
				return;
			}

			currentTaskId = response.data!.task_id;
			currentStatusFunction = invoicesApi.getRevertStatus;
			progressDialogTitle = m.invoice_list_progress_title_revert_invoice();
			progressDialogSteps = invoiceRevertSteps;
			showProgressDialog = true;
		} catch (e) {
			console.error('Error al iniciar des-actualización de factura:', e);
			openProgressErrorDialog(
				'No se pudo iniciar la desactualización de la factura',
				m.invoice_list_toasts_revert_start_error()
			);
		}
	}

	async function handleGenerateCove(recipientEmail = coveRecipientEmail) {
		if (!selectedInvoice || !companyStore.activeCompany) {
			toast.info(m.invoice_list_toasts_select_invoice_for_cove());
			return;
		}

		const selectedRecipientEmail = normalizeEmail(recipientEmail);
		if (!selectedRecipientEmail) {
			toast.error(m.invoice_list_toasts_select_recipient_email_for_cove());
			return;
		}

		const companyId = companyStore.activeCompany.id;

		// Paso 1: Checar elegibilidad antes de disparar la tarea
		try {
			const elig = await invoicesApi.checkCoveEligibility(selectedInvoice.id, companyId);
			if (elig.error) {
				toast.error(
					m.invoice_list_toasts_cove_eligibility_error_prefix({ error: String(elig.error) })
				);
				return;
			}
			if (elig.data && !elig.data.can_generate) {
				const msg =
					elig.data.reasons
						?.map((r) => `• ${r.message}`)
						.join('\n') ||
					m.invoice_list_toasts_cove_requirements_not_met();
				toast.error(msg);
				return;
			}
		} catch (e) {
			console.error('Error verificando elegibilidad COVE:', e);
			toast.error(m.invoice_list_toasts_cove_verification_error());
			return;
		}

		// Paso 2: Disparar tarea Celery de COVE
		try {
				const response = await invoicesApi.generateCove(
					selectedInvoice.id,
					companyId,
					selectedRecipientEmail
				);

			if (response.error) {
				toast.error(
					m.invoice_list_toasts_cove_start_error_prefix({ error: String(response.error) })
				);
				return;
			}

				isCoveDialogOpen = false;

			currentTaskId = response.data!.task_id;
			currentStatusFunction = invoicesApi.getCoveStatus;
			progressDialogTitle = m.invoice_list_progress_title_validate_cove();
			// Para COVE queremos UNA sola barra de progreso que refleje
			// directamente el porcentaje reportado por VU, sin pasos fijos.
			progressDialogSteps = null;
			showProgressDialog = true;
		} catch (e) {
			console.error('Error al iniciar generación de COVE:', e);
			toast.error(m.invoice_list_toasts_cove_start_error());
		}
	}

	// Pasos del procesamiento de factura (deben coincidir con el backend)
	const invoiceProcessSteps = [
		{ label: m.invoice_list_steps_load_invoice(), percent: 5 },
		{ label: m.invoice_list_steps_validate_invoice_data(), percent: 10 },
		{ label: m.invoice_list_steps_review_classes_exchange_rate(), percent: 30 },
		{ label: m.invoice_list_steps_calculate_item_values(), percent: 50 },
		{ label: m.invoice_list_steps_validate_items(), percent: 70 },
		{ label: m.invoice_list_steps_validate_rule8_quotas(), percent: 85 },
		{ label: m.invoice_list_steps_update_totals(), percent: 95 }
	];

	const invoiceRevertSteps = [
		{ label: m.invoice_list_steps_load_invoice(), percent: 5 },
		{ label: m.invoice_list_steps_validate_invoice_status(), percent: 10 },
		{ label: m.invoice_list_steps_verify_item_balances(), percent: 40 },
		{ label: m.invoice_list_steps_confirm_changes(), percent: 95 }
	];

	const invoiceCoveSteps = [
		{ label: 'Validando factura para COVE', percent: 10 },
		{ label: 'Validando configuración VU', percent: 30 },
		{ label: 'Validando emisor/destinatario', percent: 50 },
		{ label: 'Validando mercancías para COVE', percent: 80 },
		{ label: 'Finalizando validaciones de COVE', percent: 95 }
	];

	let isDownloadingCoveReceipt = $state(false);

	async function handleDownloadCoveReceipt() {
		if (!selectedInvoice || !companyStore.activeCompany) {
			toast.info(m.invoice_list_toasts_select_invoice_for_cove());
			return;
		}
		isDownloadingCoveReceipt = true;
		try {
			const blob = await invoicesApi.getCoveReceipt(
				selectedInvoice.id,
				companyStore.activeCompany.id,
				true
			);
			const url = URL.createObjectURL(blob);
			const a = document.createElement('a');
			a.href = url;
			a.download = `acuse_cove_${selectedInvoice.invoice_number || selectedInvoice.id}.pdf`;
			document.body.appendChild(a);
			a.click();
			URL.revokeObjectURL(url);
			document.body.removeChild(a);
			toast.success('Acuse de COVE descargado correctamente.');
		} catch (e: any) {
			const msg =
				e?.message ||
				'Error al obtener el Acuse de COVE. Verifica que la factura tenga COVE generado.';
			toast.error(msg);
		} finally {
			isDownloadingCoveReceipt = false;
		}
	}

	// Todas las opciones de tipo de factura con su operación correspondiente
	const allInvoiceTypeOptions = $derived(() => {
		const options = [{ value: '', label: m.invoice_list_operation_types_all(), operation: 'both' }];
		if (data.invoiceTypes) {
			data.invoiceTypes.forEach((type: any) => {
				options.push({
					value: type.key,
					label: type.description,
					operation: type.operation
				});
			});
		}
		return options;
	});

	const invoiceTypeOptions = $derived(() => {
		const allOptions = allInvoiceTypeOptions();
		if (!filters.operation_type) {
			return allOptions;
		}
		return allOptions.filter(
			(option) => option.operation === 'both' || option.operation === filters.operation_type
		);
	});

	function closeProgressDialog() {
		showProgressDialog = false;
		currentTaskId = null;
		currentStatusFunction = null;
		progressDialogSteps = null;
	}

	function openProgressErrorDialog(title: string, description: string) {
		progressErrorTitle = title;
		progressErrorDescription = humanizeLineReferences(description.trim()) || description;
		isProgressErrorOpen = true;
	}

	// --- AQUÍ PASAMOS LA FUNCIÓN DE DESCARGA A LAS COLUMNAS ---
	const columns = createColumns(handleSuccess);
	async function handleModalConfirm(
		type: string,
		format: string,
		currency: string,
		uomSource: string,
		weightUnit: string
	) {
		if (!selectedInvoice || !companyStore.activeCompany) return;

		try {
			// 1. Trigger: Start celery task with selected options
			// Note: uomSource and weightUnit are UI-only for now
			const { task_id } = await invoicesReportsApi.triggerPdfGeneration(
				selectedInvoice.id,
				companyStore.activeCompany.id,
				type,
				currency
			);

			// 2. Open Progress Dialog
			currentTaskId = task_id;
			currentStatusFunction = invoicesReportsApi.getTaskStatus;
			showProgressDialog = true;
		} catch (error: any) {
			console.error(error);
			toast.error(error.message || m.invoice_list_toasts_download_start_error());
		}
	}
</script>

{#if !canViewInvoiceSection}
	<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">
	<a
		href="#invoice-list-footer"
		class="sr-only focus:fixed focus:left-4 focus:top-20 focus:z-[60] focus:m-0 focus:inline-flex focus:h-auto focus:w-auto focus:overflow-visible focus:whitespace-normal focus:[clip-path:none] focus:rounded-md focus:border focus:bg-background focus:px-3 focus:py-2 focus:text-sm focus:shadow-md focus:outline-none focus:ring-2 focus:ring-ring"
	>
		{m.invoice_list_skip_to_actions()}
	</a>
	<div class="flex items-center justify-between">
		<div>
			<h1 class="text-2xl font-bold tracking-tight">{viewTitle}</h1>
			<p class="text-muted-foreground">{m.invoice_list_header_description()}</p>
		</div>
		<div class="flex flex-wrap items-center gap-2">
			<Button variant="outline" class="h-9" onclick={() => goto('/dashboard/invoices/settings')}>
				<Settings class="mr-2" size={16} />
				{m.invoice_list_actions_parameters()}
			</Button>
			{#if canCreateInvoice}
				<Button class="h-9" onclick={handleCreateClick}>
					<Plus class="mr-2" size={16} />
					{m.invoice_list_actions_new_invoice()}
				</Button>
			{/if}
		</div>
	</div>



	{#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}

	<Card.Root class="border bg-background flex flex-col">
		<Card.Header>
			<div class="flex items-center justify-between">
				<div>
					<Card.Title>{m.invoice_list_card_invoice_list_title()}</Card.Title>
				</div>
				<div class="flex flex-wrap items-center gap-2">
					{#if filters.operation_type === 'exp'}
						<select
							id="filter-invoice-type"
							bind:value={filters.invoice_type}
							class="flex h-9 w-[min(100%,260px)] shrink-0 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={m.invoice_list_filters_invoice_type_label()}
						>
							{#each invoiceTypeOptions() as option}
								<option value={option.value}>
									{option.value === '' ? m.invoice_list_filters_invoice_type_all_option() : option.label}
								</option>
							{/each}
						</select>
					{/if}
					<Input
						bind:value={filters.invoice_number}
						placeholder={m.invoice_list_filters_invoice_number_placeholder()}
						class="w-32 lg:w-48 h-9 bg-card"
					/>
					<Input
						bind:value={filters.year_from}
						placeholder={m.invoice_list_filters_year_start_placeholder()}
						class="w-24 h-9 bg-card"
						maxlength={4}
					/>
					<span class="text-sm text-muted-foreground">-</span>
					<Input
						bind:value={filters.year_to}
						placeholder={m.invoice_list_filters_year_end_placeholder()}
						class="w-24 h-9 bg-card"
						maxlength={4}
					/>
					<Button variant="outline" size="sm" class="h-9" onclick={reloadData}>
						<RefreshCw class="mr-2 h-4 w-4" />
						{m.invoice_list_actions_refresh()}
					</Button>
				</div>
			</div>
		</Card.Header>
		<Card.Content class="p-0">
			<div class="rounded-md border bg-background">
				<DataTable
					data={allItems}
					columns={createColumns()}
					{loading}
					{hasMore}
					{loadMore}
					selectedIds={selectedInvoiceIds}
					onRowClick={handleRowClick}
					{sorting}
					onSortingChange={(newSorting) => (sorting = newSorting)}
				/>
			</div>
		</Card.Content>
	</Card.Root>

	<div class="flex-none text-sm text-muted-foreground">
		{m.invoice_list_summary_showing()} {allItems.length} {m.invoice_list_summary_of()} {totalItems} {m.invoice_list_summary_records()}
		<span class="ml-2">•</span>
		<span class="ml-2"
			>{m.invoice_list_filters_active_filters()}: {Object.values(filters).filter((value) => value !== '').length}</span
		>
	</div>

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

	<Dialog.Root bind:open={isCoveDialogOpen}>
		<Dialog.Content class="sm:!max-w-2xl">
			<Dialog.Header>
				<Dialog.Title>{m.invoice_list_cove_dialog_title()}</Dialog.Title>
				<Dialog.Description>
					{m.invoice_list_cove_dialog_description_prefix()}
					<strong>{selectedInvoice?.invoice_number}</strong>.
				</Dialog.Description>
			</Dialog.Header>

			<Card.Root class="border bg-card/90 shadow-none">
				<Card.Content class="space-y-4 p-4 sm:p-5">
					<div class="space-y-2">
						<Label for="cove-recipient">{m.invoice_list_cove_dialog_recipient_label()}</Label>
						<Select.Root bind:value={coveRecipientEmail}>
							<Select.Trigger
								id="cove-recipient"
								class="h-auto min-h-14 w-full bg-background px-3 py-2"
								disabled={coveRecipientsLoading || coveRecipientOptions.length === 0}
							>
								{#snippet children()}
									<div class="flex min-w-0 flex-1 items-center gap-3 text-left">
										<div class="flex size-9 shrink-0 items-center justify-center rounded-full bg-muted">
											<Mail class="size-4 text-muted-foreground" />
										</div>
										<div class="min-w-0 flex-1">
											<div class="text-[11px] uppercase tracking-[0.16em] text-muted-foreground">
												{m.invoice_list_cove_dialog_destination()}
											</div>
											<div class="truncate text-sm font-medium">
												{selectedCoveRecipient?.label || m.invoice_list_cove_dialog_select_email()}
											</div>
											<div class="truncate text-xs text-muted-foreground">
												{selectedCoveRecipient?.email || m.invoice_list_cove_dialog_fallback_email()}
											</div>
										</div>
									</div>
								{/snippet}
							</Select.Trigger>
							<Select.Content searchable searchPlaceholder={m.invoice_list_cove_dialog_search_email()}>
								{#if coveRecipientsLoading}
									<div class="px-2 py-3 text-sm text-muted-foreground">
										{m.invoice_list_cove_dialog_loading_emails()}
									</div>
								{:else if coveRecipientOptions.length === 0}
									<div class="px-2 py-3 text-sm text-muted-foreground">
										{m.invoice_list_cove_dialog_no_emails()}
									</div>
								{:else}
									{#each coveRecipientOptions as recipient}
										<Select.Item
											value={recipient.email}
											label={recipient.label}
											searchText={`${recipient.label} ${recipient.email} ${recipient.description}`}
										>
											{#snippet children({ selected })}
												<div class="flex min-w-0 flex-1 flex-col">
													<span class="truncate font-medium">
														{recipient.label}
														{#if selected}
															<span class="ml-2 text-xs text-primary">{m.invoice_list_cove_dialog_selected_badge()}</span>
														{/if}
													</span>
													<span class="truncate text-xs text-muted-foreground">
														{recipient.description}
													</span>
												</div>
											{/snippet}
										</Select.Item>
									{/each}
								{/if}
							</Select.Content>
						</Select.Root>
						{#if coveRecipientsError}
							<p class="text-sm text-destructive">{coveRecipientsError}</p>
						{/if}
					</div>
				</Card.Content>
			</Card.Root>

			<Dialog.Footer>
				<Button variant="outline" onclick={() => (isCoveDialogOpen = false)}>
					{m.invoice_list_actions_cancel()}
				</Button>
				<Button
					onclick={() => handleGenerateCove(coveRecipientEmail)}
					disabled={coveRecipientsLoading || !coveRecipientEmail}
				>
					<Mail class="mr-2 h-4 w-4" />
					{m.invoice_list_actions_generate_cove()}
				</Button>
			</Dialog.Footer>
		</Dialog.Content>
	</Dialog.Root>

	<PdfProgressDialog
		bind:open={showProgressDialog}
		taskId={currentTaskId}
		getStatus={currentStatusFunction}
		onComplete={onPdfComplete}
		onClose={closeProgressDialog}
		title={progressDialogTitle}
		steps={
			progressDialogSteps
				? progressDialogSteps
				: progressDialogTitle === m.invoice_list_progress_title_process_invoice()
					? invoiceProcessSteps
					: progressDialogTitle === m.invoice_list_progress_title_revert_invoice()
						? invoiceRevertSteps
						: []
		}
		completeMessage={
			progressDialogTitle === m.invoice_list_progress_title_process_invoice()
				? m.invoice_list_progress_complete_processed()
				: progressDialogTitle === m.invoice_list_progress_title_revert_invoice()
					? m.invoice_list_progress_complete_reverted()
					: progressDialogTitle === m.invoice_list_progress_title_validate_cove()
						? m.invoice_list_progress_complete_cove_validation()
						: m.invoice_list_progress_complete_default()
		}
	/>

	<AlertDialog.Root bind:open={isProgressErrorOpen}>
		<AlertDialog.Content>
			<AlertDialog.Header>
				<AlertDialog.Title>{progressErrorTitle}</AlertDialog.Title>
				<AlertDialog.Description>
					<div class="rounded-lg border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive whitespace-pre-line">
						{progressErrorDescription}
					</div>
				</AlertDialog.Description>
			</AlertDialog.Header>
			<AlertDialog.Footer>
				<AlertDialog.Action onclick={() => (isProgressErrorOpen = false)}>
					Cerrar
				</AlertDialog.Action>
			</AlertDialog.Footer>
		</AlertDialog.Content>
	</AlertDialog.Root>

	<AlertDialog.Root bind:open={isRevertConfirmOpen}>
		<AlertDialog.Content>
			<AlertDialog.Header>
				<AlertDialog.Title>
					{selectedInvoice?.operation_type === 'exp'
						? m.invoice_list_dialogs_revert_title_export()
						: m.invoice_list_dialogs_revert_title_import()}
				</AlertDialog.Title>
				<AlertDialog.Description>
					{m.invoice_list_dialogs_revert_description_intro()} <strong>{selectedInvoice?.invoice_number}</strong>.
					{m.invoice_list_dialogs_revert_description_warning()}
					{m.invoice_list_dialogs_revert_description_question()}
				</AlertDialog.Description>
			</AlertDialog.Header>
			<AlertDialog.Footer>
				<AlertDialog.Cancel>{m.invoice_list_actions_cancel()}</AlertDialog.Cancel>
				<AlertDialog.Action onclick={confirmRevertInvoice}>{m.invoice_list_actions_continue()}</AlertDialog.Action>
			</AlertDialog.Footer>
		</AlertDialog.Content>
	</AlertDialog.Root>

	<AlertDialog.Root bind:open={isWinsaiiConfirmOpen}>
		<AlertDialog.Content>
			<AlertDialog.Header>
				<AlertDialog.Title>{m.invoice_list_dialogs_winsaai_title()}</AlertDialog.Title>
				<AlertDialog.Description>
					{m.invoice_list_dialogs_winsaai_description_intro()} <strong>{selectedInvoice?.invoice_number}</strong>
					{m.invoice_list_dialogs_winsaai_of_type()} <strong>{selectedInvoice?.document_type}</strong>
					{m.invoice_list_dialogs_winsaai_description_process()}
					{m.invoice_list_dialogs_winsaai_description_question()}
				</AlertDialog.Description>
			</AlertDialog.Header>
			<AlertDialog.Footer>
				<AlertDialog.Cancel>{m.invoice_list_actions_cancel()}</AlertDialog.Cancel>
				<AlertDialog.Action onclick={confirmWinsaiiGeneration}>{m.invoice_list_actions_continue()}</AlertDialog.Action>
			</AlertDialog.Footer>
		</AlertDialog.Content>
	</AlertDialog.Root>

	{#if showVuSubmenu}
		<!-- Capa para cerrar el submenú al hacer click fuera -->
		<button
			type="button"
			class="fixed inset-0 z-40 cursor-default border-0 bg-transparent p-0 [&:focus-visible]:outline-none"
			aria-label={m.invoice_list_actions_close()}
			onclick={() => (showVuSubmenu = false)}
			oncontextmenu={(event) => {
				event.preventDefault();
				showVuSubmenu = false;
			}}
		></button>
		<!-- Submenú contextual de Interface VU -->
		<div
			class="fixed z-50 min-w-48 rounded-md border bg-popover p-1 text-sm shadow-md"
			style={`top: ${vuSubmenuPosition.y}px; left: ${vuSubmenuPosition.x}px;`}
		>
			<button
				type="button"
				class="flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent"
				onclick={() => {
					showVuSubmenu = false;
					openCoveDialog();
				}}
			>
				<Files class="mr-2 h-4 w-4" />
				<span>{m.invoice_list_footer_vu_consult()}</span>
			</button>
			<button
				type="button"
				class="flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent"
				onclick={() => {
					showVuSubmenu = false;
					toast.info(m.invoice_list_submenu_addenda_soon());
				}}
			>
				<Files class="mr-2 h-4 w-4" />
				<span>{m.invoice_list_footer_vu_addenda()}</span>
			</button>
		<button
			type="button"
			class="flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent"
			disabled={isDownloadingCoveReceipt}
			onclick={() => {
				showVuSubmenu = false;
				handleDownloadCoveReceipt();
			}}
		>
			<Files class="mr-2 h-4 w-4" />
			<span>
				{#if isDownloadingCoveReceipt}
					Descargando...
				{:else}
					{m.invoice_list_footer_vu_cove_receipt()}
				{/if}
			</span>
		</button>
			<button
				type="button"
				class="flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent"
				onclick={() => {
					showVuSubmenu = false;
					toast.info(m.invoice_list_submenu_massive_cove_soon());
				}}
			>
				<Files class="mr-2 h-4 w-4" />
				<span>{m.invoice_list_footer_vu_massive_cove()}</span>
			</button>
		</div>
	{/if}

	<!-- Footer fijo con botones de acción -->
	<div
		id="invoice-list-footer"
		tabindex="-1"
		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
				role="toolbar"
				tabindex="-1"
				aria-label={m.invoice_list_footer_toolbar_aria()}
				data-invoice-footer-toolbar
				class="flex w-full items-center justify-end gap-2"
				onkeydown={handleInvoiceFooterToolbarKeydown}
			>
				{#if hasSelection}
					<div transition:fly={{ x: 40, duration: 250 }} class="flex items-center gap-2">
						<!-- Dropdown: Reportes -->
						<DropdownMenu.Root
							open={reportesMenuOpen}
							onOpenChange={(v) => {
								reportesMenuOpen = v;
							}}
						>
							<DropdownMenu.Trigger>
								{#snippet child({ props })}
									<Button
										{...props}
										variant="outline"
										size="sm"
										disabled={selectedInvoiceIds.length !== 1}
										data-footer-action="reportes"
									>
											{m.invoice_list_actions_reports()}
										<ChevronUp class="ml-2 h-4 w-4" />
									</Button>
								{/snippet}
							</DropdownMenu.Trigger>
							<DropdownMenu.Content
								align="end"
								class="max-h-[400px] w-56 overflow-y-auto"
								data-invoice-footer-dropdown="reportes"
							>
								<DropdownMenu.Group>
									<DropdownMenu.Label>{m.invoice_list_actions_downloads()}</DropdownMenu.Label>
									<DropdownMenu.Item onclick={() => (isDownloadModalOpen = true)}>
										<FileText class="mr-2 h-4 w-4" />
										{m.invoice_list_footer_invoice_pdf()}
									</DropdownMenu.Item>
									<DropdownMenu.Item
										onclick={() => toast.info(m.invoice_list_submenu_generate_invoice_csv_soon())}
									>
										<Download class="mr-2 h-4 w-4" />
										{m.invoice_list_footer_invoice_csv()}
									</DropdownMenu.Item>
									<DropdownMenu.Item
										onclick={() => selectedInvoice && handleDownloadConsolidated(selectedInvoice)}
									>
										<Boxes class="mr-2 h-4 w-4" />
										{m.invoice_list_footer_consolidated()}
									</DropdownMenu.Item>
									<DropdownMenu.Item
										onclick={() =>
											selectedInvoice && handleDownloadAvisoConsolidado(selectedInvoice)}
									>
										<Boxes class="mr-2 h-4 w-4" />
										{m.invoice_list_footer_consolidated_notice()}
									</DropdownMenu.Item>
									<DropdownMenu.Item
										onclick={() => selectedInvoice && handleDownloadPackingList(selectedInvoice)}
									>
										<Package class="mr-2 h-4 w-4" />
										{m.invoice_list_footer_packing_list()}
									</DropdownMenu.Item>
									<DropdownMenu.Item onclick={() => toast.info(m.invoice_list_submenu_four_copies_soon())}>
										<Files class="mr-2 h-4 w-4" />
										{m.invoice_list_footer_four_copies_rem()}
									</DropdownMenu.Item>
									{#if selectedInvoice?.operation_type === 'exp'}
										<DropdownMenu.Item onclick={() => handleDownloadDescargo(selectedInvoice)}>
											<ClipboardList class="mr-2 h-4 w-4" />
											{m.invoice_list_footer_descargo_peps()}
										</DropdownMenu.Item>
									{/if}
								</DropdownMenu.Group>
							</DropdownMenu.Content>
						</DropdownMenu.Root>

						<!-- Dropdown: Más Acciones -->
						<DropdownMenu.Root
							open={masAccionesMenuOpen}
							onOpenChange={(open) => {
								masAccionesMenuOpen = open;
								if (!open) {
									showVuSubmenu = false;
								}
							}}
						>
							<DropdownMenu.Trigger>
								{#snippet child({ props })}
									<Button
										{...props}
										variant="outline"
										size="sm"
										disabled={selectedInvoiceIds.length !== 1}
										data-footer-action="mas-acciones"
									>
											{m.invoice_list_actions_more_actions()}
										<ChevronUp class="ml-2 h-4 w-4" />
									</Button>
								{/snippet}
							</DropdownMenu.Trigger>
							<DropdownMenu.Content
								align="end"
								class="max-h-[400px] w-56 overflow-y-auto"
								data-invoice-footer-dropdown="mas-acciones"
							>
								<DropdownMenu.Group>
									<DropdownMenu.Label>{m.invoice_list_actions_other_actions()}</DropdownMenu.Label>
									<DropdownMenu.Item
										onclick={() => (isTransferenciaModalOpen = true)}
										disabled={!companyStore.activeCompany}
									>
										<Send class="mr-2 h-4 w-4" />
										{m.invoice_list_footer_transferencia_electronica()}
									</DropdownMenu.Item>
									<!-- Interface VU: click izquierdo = COVE, click derecho = submenú contextual (overlay) -->
									<DropdownMenu.Item
										class="cursor-pointer"
										onclick={() => openCoveDialog()}
										oncontextmenu={(event) => {
											event.preventDefault();
											event.stopPropagation();
											const target = event.currentTarget as HTMLElement;
											const rect = target.getBoundingClientRect();
											vuSubmenuPosition = {
												x: rect.right,
												y: rect.top
											};
											showVuSubmenu = true;
										}}
									>
										<MonitorUp class="mr-2 h-4 w-4" />
										<span>{m.invoice_list_footer_interface_vu()}</span>
									</DropdownMenu.Item>
									<!-- Mismas acciones VU accesibles sin mouse (bits-ui Sub) -->
									<DropdownMenu.Sub>
										<DropdownMenu.SubTrigger>
											<MonitorUp class="mr-2 h-4 w-4" />
											{m.invoice_list_footer_vu_options_keyboard()}
										</DropdownMenu.SubTrigger>
										<DropdownMenu.SubContent class="w-56">
											<DropdownMenu.Item
											onclick={() => openCoveDialog()}
											>
												<Files class="mr-2 h-4 w-4" />
												{m.invoice_list_footer_vu_consult()}
											</DropdownMenu.Item>
											<DropdownMenu.Item onclick={() => toast.info(m.invoice_list_submenu_addenda_soon())}>
												<Files class="mr-2 h-4 w-4" />
												{m.invoice_list_footer_vu_addenda()}
											</DropdownMenu.Item>
										<DropdownMenu.Item
											disabled={isDownloadingCoveReceipt}
											onclick={() => handleDownloadCoveReceipt()}
										>
											<Files class="mr-2 h-4 w-4" />
											{isDownloadingCoveReceipt ? 'Descargando...' : m.invoice_list_footer_vu_cove_receipt()}
										</DropdownMenu.Item>
											<DropdownMenu.Item onclick={() => toast.info(m.invoice_list_submenu_massive_cove_soon())}>
												<Files class="mr-2 h-4 w-4" />
												{m.invoice_list_footer_vu_massive_cove()}
											</DropdownMenu.Item>
										</DropdownMenu.SubContent>
									</DropdownMenu.Sub>
										<DropdownMenu.Item onclick={() => toast.info(m.invoice_list_submenu_cons_sed_soon())}>
										<ScrollText class="mr-2 h-4 w-4" />
											{m.invoice_list_footer_cons_sed()}
									</DropdownMenu.Item>
										<DropdownMenu.Item onclick={() => toast.info(m.invoice_list_submenu_encomienda_soon())}>
										<BadgeCent class="mr-2 h-4 w-4" />
											{m.invoice_list_footer_encomienda()}
									</DropdownMenu.Item>
									<DropdownMenu.Item
											onclick={() => toast.info(m.invoice_list_submenu_fact_mex_cons_soon())}
									>
										<FileText class="mr-2 h-4 w-4" />
											{m.invoice_list_footer_fact_mex_cons()}
									</DropdownMenu.Item>
									<DropdownMenu.Item
											onclick={() => toast.info(m.invoice_list_submenu_fact_mex_ord_cat_soon())}
									>
										<FileText class="mr-2 h-4 w-4" />
											{m.invoice_list_footer_fact_mex_ord_cat()}
									</DropdownMenu.Item>
										<DropdownMenu.Item onclick={() => toast.info(m.invoice_list_submenu_export_sia_soon())}>
										<Database class="mr-2 h-4 w-4" />
											{m.invoice_list_footer_export_sia()}
									</DropdownMenu.Item>
										<DropdownMenu.Item onclick={() => toast.info(m.invoice_list_submenu_interface_soon())}>
										<ArrowRightLeft class="mr-2 h-4 w-4" />
											{m.invoice_list_footer_interface()}
									</DropdownMenu.Item>
								</DropdownMenu.Group>
							</DropdownMenu.Content>
						</DropdownMenu.Root>
						<div class="h-6 w-px bg-border"></div>
					</div>
				{/if}
				<!-- Procesa la factura seleccionada mediante tarea Celery -->
				<Button
					variant="outline"
					size="sm"
					disabled={loading || selectedInvoiceIds.length !== 1 || !canProcessSelected}
					onclick={handleProcessInvoice}
					data-footer-action="procesar"
				>
					<RefreshCw class="mr-2 h-4 w-4" />
					{m.invoice_list_footer_process_update()}
				</Button>
				<Button
					variant="outline"
					size="sm"
					disabled={loading || selectedInvoiceIds.length !== 1 || !canProcessSelected}
					onclick={() => (isRevertConfirmOpen = true)}
					data-footer-action="desactualizar"
				>
					<RotateCcw class="mr-2 h-4 w-4" />
					{m.invoice_list_footer_unprocess()}
				</Button>
				<Button
					variant="outline"
					size="sm"
					disabled={selectedInvoiceIds.length !== 1 || !canViewSelected}
					onclick={() => (showDetailsDialog = true)}
					data-footer-action="detalles"
				>
					<Eye class="mr-2 h-4 w-4" />
					{m.invoice_list_footer_view_details()}
				</Button>

				<Button
					variant="outline"
					size="sm"
					onclick={() => selectedInvoice && handleInterfaceAgenteAduanal(selectedInvoice)}
					disabled={!selectedInvoice}
					data-footer-action="interface-aa"
				>
					<Send class="mr-2 h-4 w-4" />
					{m.invoice_list_footer_customs_broker_interface()}
				</Button>

				<Button
					variant="outline"
					size="sm"
					disabled={selectedInvoiceIds.length !== 1 || !canEditSelected}
					onclick={handleEditSelected}
					data-footer-action="editar"
				>
					<Pencil class="mr-2 h-4 w-4" />
					{m.invoice_list_footer_edit()}
				</Button>
				<Button
					variant="outline"
					size="sm"
					disabled={selectedInvoiceIds.length === 0 || !canDeleteSelection}
					onclick={() => (showDeleteDialog = true)}
					data-footer-action="eliminar"
				>
					<Trash2 class="mr-2 h-4 w-4" />
					{m.invoice_list_footer_delete()}
				</Button>
				<!-- (COVE) La acción vive en el menú \"Interface VU\" de Más Acciones, no en esta barra -->
			</div>
		</div>
	</div>

	<!-- ... -->

	{#if companyStore.activeCompany}
		<InvoiceDownloadModal bind:open={isDownloadModalOpen} onConfirm={handleModalConfirm} />
		<TransferenciaElectronicaModal bind:open={isTransferenciaModalOpen} invoice={selectedInvoice} />
	{/if}

	{#if showDetailsDialog && selectedInvoice}
		<DetailsDialog invoice={selectedInvoice} onClose={() => (showDetailsDialog = false)} />
	{/if}

	{#if showDeleteDialog}
		<DeleteDialog
			invoice={selectedInvoice}
			invoicesToDelete={selectedInvoiceIds
				.map((id) => allItems.find((i) => i.id === id))
				.filter((i): i is Invoice => i !== undefined)}
			onClose={() => {
				showDeleteDialog = false;
				selectedInvoiceIds = [];
			}}
			onSuccess={() => {
				showDeleteDialog = false;
				selectedInvoiceIds = [];
				handleSuccess();
			}}
		/>
	{/if}
</div>
{/if}
