<script lang="ts" generics="TData, TValue">
	import { onMount } from 'svelte';
	import { type ColumnDef, getCoreRowModel } from '@tanstack/table-core';
	import { createSvelteTable, FlexRender } from '$lib/components/ui/data-table/index.js';
	import * as Table from '$lib/components/ui/table/index.js';
	import { m } from '$lib/i18n/messages';

	type DataTableProps<TData, TValue> = {
		columns: ColumnDef<TData, TValue>[];
		data: TData[];
		loading: boolean;
		hasMore: boolean;
		loadMore: () => void;
		// Props para selección
		selectedIds?: number[];
		onRowClick?: (row: TData) => void;
		compact?: boolean;
		sorting?: import("@tanstack/table-core").SortingState;
		onSortingChange?: (sorting: import("@tanstack/table-core").SortingState) => void;
	};

	let {
		data,
		columns,
		loading,
		hasMore,
		loadMore,
		selectedIds = [],
		onRowClick,
		compact = false,
		sorting = [],
		onSortingChange
	}: DataTableProps<TData, TValue> = $props();

	const table = createSvelteTable({
		get data() {
			return data;
		},
		columns,
		getCoreRowModel: getCoreRowModel(),
		getRowId: (row: any) => row.id?.toString(), // Usar ID para identificar filas
		state: {
			get rowSelection() {
				// Mapear los IDs seleccionados al formato que espera TanStack Table
				const selection: Record<string, boolean> = {};
				selectedIds.forEach((id) => {
					selection[id.toString()] = true;
				});
				return selection;
			},
			get sorting() {
				return sorting;
			}
		},
		onStateChange: (updater: any) => {
			if (onSortingChange) {
				const currentState = table.getState();
				const nextState = typeof updater === 'function' ? updater(currentState) : updater;
				
				// Identify if this was a sorting update or at least contains sorting
				if (nextState && nextState.sorting !== undefined) {
					onSortingChange(nextState.sorting);
				} else if (Array.isArray(nextState)) {
					// Fallback for when updater might return just the array slice
					onSortingChange(nextState);
				}
			}
		},
		enableRowSelection: true,
		enableMultiRowSelection: true,
		manualSorting: true // Sorting is handled server-side for this component
	});

	function handleRowDoubleClick(row: any) {
		const invoice = row.original;
		if (invoice?.id) {
			window.location.href = `/dashboard/invoices/edit/${invoice.id}`;
		}
	}

	let scrollContainer = $state<HTMLDivElement>();
	let loadingTrigger = $state<HTMLDivElement>();

	// Intersection Observer para detectar cuando el usuario llega al final
	$effect(() => {
		const target = loadingTrigger;
		const root = scrollContainer;
		if (!target) return;

		const observer = new IntersectionObserver(
			(entries) => {
				const [entry] = entries;
				if (entry.isIntersecting && hasMore && !loading) {
					loadMore();
				}
			},
			{
				root: root,
				threshold: 0.1
			}
		);

		observer.observe(target);

		return () => {
			observer.disconnect();
		};
	});
</script>

<div class="w-full">
	<div
		data-invoice-list-table
		class="catalog-table-shell min-h-[360px] max-h-[calc(100svh-420px)] overflow-auto [&_[data-slot=table-container]]:overflow-visible [&_[data-slot=table-container]]:w-full"
		bind:this={scrollContainer}
	>
		<div class="min-w-max">
			<Table.Root>
			<Table.Header class="catalog-table-header">
				{#each table.getHeaderGroups() as headerGroup (headerGroup.id)}
					{@const headerList = headerGroup.headers}
					{@const lastHeaderColId = headerList[headerList.length - 1]?.column.id}
					<Table.Row inTabOrder={false}>
						{#each headerList as header (header.id)}
							{@const colId = header.column.id}
							<Table.Head
								class={[
									colId === 'select' &&
										'catalog-table-sticky-left z-40 min-w-[2.75rem]',
									colId === lastHeaderColId &&
										'catalog-table-sticky-right z-40'
								]
									.filter(Boolean)
									.join(' ')}
							>
								{#if !header.isPlaceholder}
									<button
										class={[
											'flex w-full items-center justify-between gap-2',
											header.column.getCanSort() && 'cursor-pointer select-none'
										]
											.filter(Boolean)
											.join(' ')}
										onclick={header.column.getToggleSortingHandler()}
									>
										<FlexRender
											content={header.column.columnDef.header}
											context={header.getContext()}
										/>
										{#if header.column.getCanSort()}
											<div class="flex h-4 w-4 shrink-0 items-center justify-center">
												{#if header.column.getIsSorted() === 'asc'}
													<svg
														xmlns="http://www.w3.org/2000/svg"
														width="14"
														height="14"
														viewBox="0 0 24 24"
														fill="none"
														stroke="currentColor"
														stroke-width="2"
														stroke-linecap="round"
														stroke-linejoin="round"
														class="lucide lucide-chevron-up text-primary"
														><path d="m18 15-6-6-6 6" /></svg
													>
												{:else if header.column.getIsSorted() === 'desc'}
													<svg
														xmlns="http://www.w3.org/2000/svg"
														width="14"
														height="14"
														viewBox="0 0 24 24"
														fill="none"
														stroke="currentColor"
														stroke-width="2"
														stroke-linecap="round"
														stroke-linejoin="round"
														class="lucide lucide-chevron-down text-primary"
														><path d="m6 9 6 6 6-6" /></svg
													>
												{:else}
													<svg
														xmlns="http://www.w3.org/2000/svg"
														width="14"
														height="14"
														viewBox="0 0 24 24"
														fill="none"
														stroke="currentColor"
														stroke-width="2"
														stroke-linecap="round"
														stroke-linejoin="round"
														class="lucide lucide-chevrons-up-down opacity-30 group-hover:opacity-100"
														><path d="m7 15 5 5 5-5" /><path d="m7 9 5-5 5 5" /></svg
													>
												{/if}
											</div>
										{/if}
									</button>
								{/if}
							</Table.Head>
						{/each}
					</Table.Row>
				{/each}
			</Table.Header>
			<Table.Body>
				{#each table.getRowModel().rows as row (row.id)}
					{@const visibleCells = row.getVisibleCells()}
					{@const lastCellColId = visibleCells[visibleCells.length - 1]?.column.id}
					<Table.Row
						data-invoice-data-row
						data-state={row.getIsSelected() && 'selected'}
						class="group/inv-list cursor-pointer {row.getIsSelected() ? 'catalog-table-row-selected' : 'catalog-table-row'}"
						onclick={() => onRowClick && onRowClick(row.original)}
						ondblclick={() => handleRowDoubleClick(row)}
					>
						{#each visibleCells as cell (cell.id)}
							{@const colId = cell.column.id}
							<Table.Cell
								class={[
									colId === 'select' &&
										'catalog-table-sticky-left z-30 min-w-[2.75rem]',
									colId === lastCellColId &&
										'catalog-table-sticky-right z-30',
									row.getIsSelected()
										? 'catalog-table-sticky-row-selected'
										: 'catalog-table-sticky-row-hover'
								]
									.filter(Boolean)
									.join(' ')}
							>
								<FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
							</Table.Cell>
						{/each}
					</Table.Row>
				{:else}
					<Table.Row inTabOrder={false}>
						<Table.Cell colspan={columns.length} class="h-24 text-center">
							{m.invoice_table_no_results()}
						</Table.Cell>
					</Table.Row>
				{/each}

				<!-- Loading Trigger - Se activa cuando es visible -->
				{#if hasMore}
					<Table.Row inTabOrder={false}>
						<Table.Cell colspan={columns.length} class="h-20 text-center">
							<div bind:this={loadingTrigger}>
								{#if loading}
									<div class="flex items-center justify-center gap-2">
										<div
											class="h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent"
										></div>
										<span class="text-sm text-muted-foreground">{m.invoice_table_loading_more()}</span>
									</div>
								{:else}
									<div class="text-sm text-muted-foreground">{m.invoice_table_scroll_to_load_more()}</div>
								{/if}
							</div>
						</Table.Cell>
					</Table.Row>
				{/if}
			</Table.Body>
			</Table.Root>
		</div>
	</div>
</div>
