<script lang="ts">
  import { ApiService, DataResponse } from "$bindings/changeme/api";
  import { type ColumnDef, type GlobalFilterTableState, type RowSelectionState, getCoreRowModel, getFilteredRowModel } from "@tanstack/table-core";
  import {
    createSvelteTable,
    FlexRender,
    renderComponent
  } from "$lib/components/ui/data-table/index.js";
  import * as Table from "$lib/components/ui/table/index.js";
  import Checkbox from "$lib/components/ui/checkbox/checkbox.svelte";
  import type { concept as conceptType } from "$bindings/changeme/api/internal";
  import Skeleton from "$lib/components/ui/skeleton/skeleton.svelte";
  import { toast } from "svelte-sonner";
  import { Input } from "$lib/components/ui/input";
  import { Search } from "lucide-svelte";

    type Props = {
        concept?: conceptType
    }

    let { cycle, concept }: Props = $props();
    let data: DataResponse[] = $state([])
    let rowSelection = $state<RowSelectionState>({});
    let globalFilter = $state<GlobalFilterTableState>()
    let saving = $state(false)

    $effect(() => {
        data = [];
        if(concept) {
            ApiService.LoadData(concept.id).then((d) => {
                data = d;
                rowSelection = data.filter(f => f.is_assigned).reduce((acc, f) => ({ ...acc, [f.id.toString()]: f.is_assigned }), {})
            });
        }
    });

    const columns: ColumnDef<Data>[] = [
        {
            id: "select",
            accessorKey: "is_assigned",
            header: "Select",
            cell: ({ row }) => renderComponent(Checkbox, {
                                    disabled: saving,
                                    checked: row.getIsSelected(),
                                    onCheckedChange: (value) => row.toggleSelected(!!value),
                                    controlledChecked: true,
                                    "aria-label": "Select row",
                                }),
        },
        {
            id: "id",
            accessorKey: "id",
            header: "ID",
        },
        {
            id: "col1",
            accessorKey: "col1",
            header: "COL1",
        },
        {
            accessorKey: "col2",
            header: "Col2",
        },
        {
            accessorKey: "col3",
            header: "Col3",
        },
        {
            accessorKey: "day",
            cell: (row) => renderComponent(Checkbox, {
                                class: "cursor-default",
                                checked: row.cell.getValue<boolean>(),
                                onclick: (e) => e.preventDefault(),
                            }),
            header: "Day",
        },
        {
            accessorKey: "comment",
            header: "Comment",
        }
    ]

    const table = createSvelteTable({
        get data() {
            return data;
        },
        columns,
        globalFilterFn: 'includesString',
        getCoreRowModel: getCoreRowModel(),
        getFilteredRowModel: getFilteredRowModel(),
        enableMultiRowSelection: true,
        enableRowSelection: true,
        getRowId: (f) => f.id.toString(),
        onGlobalFilterChange: (updater) => {
            console.log(updater)
            if (typeof updater === "function") {
                globalFilter = updater(globalFilter);
            } else {
                globalFilter = updater;
            }
        },
        onRowSelectionChange: async (updater) => {
            if (typeof updater === "function") {
                try {
                    saving = true
                    const rs = updater(rowSelection);
                    await ApiService.Assign(concept!.id, rs)
                    rowSelection = rs
                }
                catch(e: any) {
                    toast.error(e)
                }
                finally {
                    saving = false
                }
            } else {
                rowSelection = updater;
            }
            
        },    
        initialState: {
            columnPinning: {
                left: ['select', 'id', 'col1']
            }
        },
        state: {
            get rowSelection() {
                return rowSelection;
            },
            get globalFilter() {
                return globalFilter;
            }
        }
    });
</script>

<div class="flex flex-col flex-1 w-full">
    <div class="relative">
        <Search class="text-muted-foreground absolute left-2 top-[50%] h-4 w-4 translate-y-[-50%]" />
        <Input type="text" placeholder="search" class="pl-8" on:input={(e) => table.setGlobalFilter((e.target as HTMLInputElement).value)} />
    </div>
    <Table.Root class="flex-1 w-full">
        <Table.Header>
        {#each table.getHeaderGroups() as headerGroup (headerGroup.id)}
            <Table.Row>
            {#each headerGroup.headers as header (header.id)}
                <Table.Head>
                {#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 data-state={row.getIsSelected() && "selected"}>
            {#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>
            <Table.Cell colspan={columns.length} class="h-24 text-center">
                <div class="flex flex-col gap-y-2">
                    <Skeleton class="h-4" />
                    <Skeleton class="h-4 w-1/2" />
                </div>
            </Table.Cell>
            </Table.Row>
        {/each}
        </Table.Body>
    </Table.Root>
</div>