<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 { dodaFormT } from '$lib/i18n/doda-form-strings';

	type DataTableProps<TData, TValue> = {
		columns: ColumnDef<TData, TValue>[];
		data: TData[];
		loading: boolean;
		hasMore: boolean;
		loadMore: () => void;
		selectedId?: number | null;
		onRowClick?: (row: TData) => void;
		onRowDoubleClick?: (row: TData) => void;
		/** Solo catálogo DODA: textos i18n de carga / vacío */
		locale?: 'en' | 'es';
	};

	let {
		data,
		columns,
		loading,
		hasMore,
		loadMore,
		selectedId = null,
		onRowClick,
		onRowDoubleClick,
		locale = 'es'
	}: DataTableProps<TData, TValue> = $props();

	const loc = $derived((locale === 'en' ? 'en' : 'es') as 'en' | 'es');

	const table = createSvelteTable({
		get data() {
			return data;
		},
		columns,
		getCoreRowModel: getCoreRowModel(),
		getRowId: (row: any) => row.id?.toString(),
		state: {
			get rowSelection() {
				return selectedId ? { [selectedId]: true } : {};
			}
		},
		enableRowSelection: true,
		enableMultiRowSelection: false
	});

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

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

		if (loadingTrigger) {
			observer.observe(loadingTrigger);
		}

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

<div class="w-full h-full">
	<div
		class="catalog-table-shell min-h-[360px] max-h-[calc(100svh-420px)] overflow-auto [&_[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)}
					<Table.Row inTabOrder={false}>
						{#each headerGroup.headers as header (header.id)}
							<Table.Head class="catalog-table-head-cell">
								{#if !header.isPlaceholder}
									<FlexRender
										content={header.column.columnDef.header}
										context={header.getContext()}
									/>
								{/if}
							</Table.Head>
						{/each}
					</Table.Row>
				{/each}
			</Table.Header>
			<Table.Body>
				{#each table.getRowModel().rows as row (row.id)}
					<Table.Row inTabOrder={false} data-state={row.getIsSelected() && 'selected'}
						onclick={() => onRowClick?.(row.original)}
						ondblclick={() => onRowDoubleClick?.(row.original)}
						class="cursor-pointer {row.getIsSelected() ? 'catalog-table-row-selected' : 'catalog-table-row'}"
					>
						{#each row.getVisibleCells() as cell (cell.id)}
							<Table.Cell>
								<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 text-sm text-muted-foreground">
							{dodaFormT(loc, 'list_no_results')}
						</Table.Cell>
					</Table.Row>
				{/each}

				{#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">{dodaFormT(loc, 'list_loading_more')}</span>
									</div>
								{:else}
									<div class="text-sm text-muted-foreground">{dodaFormT(loc, 'list_scroll_for_more')}</div>
								{/if}
							</div>
						</Table.Cell>
					</Table.Row>
				{/if}
			</Table.Body>
			</Table.Root>
		</div>
	</div>
</div>
