<script module>
	export { DragHandle };
</script>

<script lang="ts">
	import * as Card from '$lib/components/ui/card/index';
	import Label from '$lib/components/ui/label/label.svelte';
	import Input from '$lib/components/ui/input/input.svelte';
	import RecipeDetail from './recipe-detail.svelte';
	import {
		createTable,
		getCoreRowModel,
		getFacetedRowModel,
		getSortedRowModel,
		type ColumnDef,
		type Row,
		type RowSelectionState,
		type SortingState
	} from '@tanstack/table-core';
	import { createSvelteTable } from '../ui/data-table';
	import * as Table from '$lib/components/ui/table/index';
	import FlexRender from '../ui/data-table/flex-render.svelte';
	import ScrollArea from '../ui/scroll-area/scroll-area.svelte';
	import { type Attachment } from 'svelte/attachments';
	import Button from '../ui/button/button.svelte';
	import { GripVerticalIcon } from '@lucide/svelte/icons';
	import { DragDropProvider } from '@dnd-kit-svelte/svelte';
	import { move } from '@dnd-kit/helpers';
	import { RestrictToVerticalAxis } from '@dnd-kit/abstract/modifiers';
	import { type UniqueIdentifier } from '@dnd-kit/abstract';
	import { type RecipelistMaterial } from './columns';
	import { useSortable } from '@dnd-kit-svelte/svelte/sortable';
	import { onMount } from 'svelte';

	import { get, writable, type Writable } from 'svelte/store';

	// type DataTableProps<TData, TValue> = {
	// 	columns: ColumnDef<TData, TValue>[];
	// 	data: TData[];
	// };

	let {
		data,
		columns,
		onStateChange
	}: {
		data: RecipelistMaterial[];
		columns: ColumnDef<any, any>[];
		onStateChange: any;
	} = $props();

	let sorting = $state<SortingState>([]);
	let rowSelection = $state<RowSelectionState>({});

	// let recipeMatState = $state<RecipelistMaterial[]>(data);

	const table = createSvelteTable({
		get data() {
			return data;
		},
		columns,
		enableRowSelection: true,
		enableMultiRowSelection: true,
		getRowId: (row: any) => row.id.toString(),
		state: {
			get sorting() {
				return sorting;
			},
			get rowSelection() {
				return rowSelection;
			}
		},
		getCoreRowModel: getCoreRowModel(),
		getSortedRowModel: getSortedRowModel(),
		getFacetedRowModel: getFacetedRowModel(),
		onStateChange: async (updater) => {
			console.log('table state change', data);
			await onStateChange(table.getRowModel().rows.map((x) => x.original));
		},
		onSortingChange: async (updater) => {
			console.log('triggering sorting');
			if (typeof updater === 'function') {
				sorting = updater(sorting);
			} else {
				sorting = updater;
			}
			await onStateChange(table.getRowModel().rows.map((x) => x.original));
		},
		onRowSelectionChange: async (updater) => {
			// table.getRowModel().rows.find((x) => x.original.id == )
			if (typeof updater === 'function') {
				rowSelection = updater(rowSelection);
				let rows = table.getRowModel().rows;

				console.log('state size', data, rows);
			} else {
				rowSelection = updater;
			}
			await onStateChange(table.getRowModel().rows.map((x) => x.original));
		}
	});
</script>

<!-- use card -->
<Card.Root>
	<Card.Header>
		<Card.Title>Recipe List</Card.Title>
		<Card.Description>Material used in this menu's brewing process</Card.Description>

		<Card.Content>
			<!-- table -->

			<DragDropProvider
				modifiers={[
					// @ts-expect-error @dnd-kit/adbstract types are botched atm
					RestrictToVerticalAxis
				]}
				onDragEnd={(e) => {
					// snap
					data = move(data as any, e as any);
					//
				}}
			>
				<ScrollArea class="h-[60vh] w-full rounded-md border" type="always">
					<Table.Root class="relative w-full">
						<Table.Header class="sticky top-0 z-10">
							{#each table.getHeaderGroups() as headerGroup (headerGroup.id)}
								<Table.Row>
									{#each headerGroup.headers as header (header.id)}
										<Table.Head colspan={header.colSpan}>
											{#if !header.isPlaceholder}
												<FlexRender
													content={header.column.columnDef.header}
													context={header.getContext()}
												/>
											{/if}
										</Table.Head>
									{/each}
								</Table.Row>
							{/each}
						</Table.Header>
						<Table.Body class="**:data-[slot=table-cell]:first:w-8">
							{#if table.getRowModel().rows?.length}
								{#each table.getRowModel().rows as row, index (row.id)}
									{@render DraggableRow({ row, index })}
								{/each}
							{:else}
								<Table.Row>
									<Table.Cell colspan={columns.length} class="h-24 text-center"
										>Empty recipe.</Table.Cell
									>
								</Table.Row>
							{/if}
						</Table.Body>
					</Table.Root>
				</ScrollArea>
			</DragDropProvider>
		</Card.Content>
	</Card.Header>
</Card.Root>

{#snippet DraggableRow({ row, index }: { row: Row<any>; index: number })}
	{@const { ref, isDragging, handleRef } = useSortable({
		id: row.original.id,
		index: () => index
	})}

	<Table.Row
		data-state={row.original.is_use ? 'selected' : undefined}
		data-dragging={isDragging.current}
		class="relative z-0 data-[dragging=true]:z-10 data-[dragging=true]:opacity-80"
		{@attach ref}
	>
		{#each row.getVisibleCells() as cell (cell.id)}
			<Table.Cell>
				<FlexRender
					attach={handleRef}
					content={cell.column.columnDef.cell}
					context={cell.getContext()}
				/>
			</Table.Cell>
		{/each}
	</Table.Row>
{/snippet}

{#snippet DragHandle({ attach }: { attach: Attachment })}
	<Button
		{@attach attach}
		variant="ghost"
		size="icon"
		class="size-7 text-muted-foreground hover:bg-transparent"
	>
		<GripVerticalIcon class="size-3 text-muted-foreground" />
		<span class="sr-only">Drag to reorder</span>
	</Button>
{/snippet}
