"use client";
import React, { useEffect, cloneElement, Children, isValidElement, PropsWithChildren } from "react";
import { flexRender } from "@tanstack/react-table";
import { ChevronDown, ChevronsUpDown, ChevronUp, X } from "lucide-react";
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow
} from "@/components/ui/table";
import {
    DropdownMenu,
    DropdownMenuCheckboxItem,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuTrigger
} from "@/components/ui/dropdown-menu";
import { useResourceList } from "./resource-list-provider";
import { ResourceListRowContext } from "./resource-list-row-provider";
import { ResourceListFieldProps } from "./resource-list-field";

type Props = PropsWithChildren<{
    className?: string;
}>;

export const ResourceListTable = <T extends object = object>(props: Props) => {
    const {
        children
    } = props;

    const {
        table,
        registerColumn,
        unregisterColumn
    } = useResourceList<T>();

    const rows = table.getRowModel().rows;

    useEffect(() => {
        Children.map(children, (child, index) => {
            if(!isValidElement(child)) {
                return null;
            }

            const {
                colSpan,
                enableSorting = false,
                name,
                label
            } = child.props as ResourceListFieldProps<T, keyof T>;

            registerColumn({
                id: name ? String(name) : `col-${index}`,
                enableSorting,
                size: colSpan,
                accessorKey: name ? String(name) : undefined,
                header: ({ column }) => {
                    const title = label ?? (name ? String(name) : undefined) ?? "";

                    if(!column.getCanSort()) {
                        return <div>{title}</div>;
                    }

                    return (
                        <DropdownMenu>
                            <DropdownMenuTrigger
                              className="hover:bg-accent focus:ring-ring data-[state=open]:bg-accent [&_svg]:text-muted-foreground -ml-1.5 flex h-8 items-center gap-1.5 rounded-md px-2 py-1.5 focus:ring-1 focus:outline-none [&_svg]:size-4 [&_svg]:shrink-0">
                                {label ?? (name ? String(name) : undefined) ?? ""}

                                {column.getCanSort() && (
                                    column.getIsSorted() === 'desc' ? (
                                        <ChevronDown />
                                    ) : column.getIsSorted() === 'asc' ? (
                                        <ChevronUp />
                                    ) : (
                                        <ChevronsUpDown />
                                    )
                                )}
                            </DropdownMenuTrigger>

                            <DropdownMenuContent align="start" className="w-28">
                                {column.getCanSort() && (
                                    <>
                                        <DropdownMenuCheckboxItem
                                          className="[&_svg]:text-muted-foreground relative pr-8 pl-2 [&>span:first-child]:right-2 [&>span:first-child]:left-auto"
                                          checked={column.getIsSorted() === "asc"}
                                          onClick={() => column.toggleSorting(false)}>
                                            <ChevronUp />
                                            Asc
                                        </DropdownMenuCheckboxItem>

                                        <DropdownMenuCheckboxItem
                                          className="[&_svg]:text-muted-foreground relative pr-8 pl-2 [&>span:first-child]:right-2 [&>span:first-child]:left-auto"
                                          checked={column.getIsSorted() === "desc"}
                                          onClick={() => column.toggleSorting(true)}>
                                            <ChevronDown />
                                            Desc
                                        </DropdownMenuCheckboxItem>

                                        {column.getIsSorted() && (
                                            <DropdownMenuItem
                                              className='[&_svg]:text-muted-foreground pl-2'
                                              onClick={() => column.clearSorting()}>
                                                <X />
                                                Reset
                                            </DropdownMenuItem>
                                        )}
                                    </>
                                )}
                            </DropdownMenuContent>
                        </DropdownMenu>
                    );
                },
                cell: () => {
                    return cloneElement(child);
                }
            });
        });

        return () => {
            Children.map(children, (child, index) => {
                if(!isValidElement(child)) {
                    return null;
                }

                const {
                    name
                } = child.props as ResourceListFieldProps<T, keyof T>;

                unregisterColumn(name ? String(name) : `col-${index}`);
            });
        };
    }, [children, registerColumn, unregisterColumn]);

    return (
        <div className="overflow-hidden rounded-md border">
            <Table>
                <TableHeader>
                    {table.getHeaderGroups().map((headerGroup) => {
                        return (
                            <TableRow key={headerGroup.id}>
                                {headerGroup.headers.map((header) => {
                                    return (
                                        <TableHead key={header.id} colSpan={header.colSpan}>
                                            {!header.isPlaceholder && (
                                                flexRender(
                                                    header.column.columnDef.header,
                                                    header.getContext()
                                                )
                                            )}
                                        </TableHead>
                                    );
                                })}
                            </TableRow>
                        );
                    })}
                </TableHeader>

                <TableBody>
                    {rows.length === 0 && (
                        <TableRow>
                            <TableCell
                              className='h-24 text-center'
                              colSpan={999}>
                                No results.
                            </TableCell>
                        </TableRow>
                    )}

                    {rows.map((row) => {
                        return (
                            <TableRow
                              key={row.id}>
                                <ResourceListRowContext
                                  value={{
                                    row: row.original
                                  }}>
                                    {row.getVisibleCells().map((cell) => {
                                        return (
                                            <TableCell
                                              key={cell.id}>
                                                {flexRender(
                                                    cell.column.columnDef.cell,
                                                    cell.getContext()
                                                )}
                                            </TableCell>
                                        );
                                    })}
                                </ResourceListRowContext>
                            </TableRow>
                        );
                    })}
                </TableBody>
            </Table>
        </div>
    );
};
