"use client"
import { Button } from "@/components/ui/button"
import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuTrigger,
} from "@/components/ui/context-menu"
import {
  DropdownMenu,
  DropdownMenuCheckboxItem,
  DropdownMenuContent,
  DropdownMenuTrigger,
  DropdownMenuRadioItem,
  DropdownMenuRadioGroup
} from "@/components/ui/dropdown-menu"
import { Input } from "@/components/ui/input"
import { Component, ComponentProps, use, useState } from "react"
import {
  ColumnDef,
  flexRender,
  SortingState,
  getSortedRowModel,
  ColumnFiltersState,
  VisibilityState,
  getFilteredRowModel,
  getCoreRowModel,
  getPaginationRowModel,
  useReactTable
} from "@tanstack/react-table"

import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
import { EyeIcon, Trash2 } from "lucide-react"
import { usePathname } from "next/navigation"
import FormContextMenu from "./contextMenu"
import { deleteRecords } from "app/lib/del"
import { Pathname } from "app/types"
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTrigger } from "@/components/ui/dialog"
import pluralize from "app/lib/pluralize"
import { updateTextField } from "app/lib/update"

export interface DataTableProps<TData, TValue> {
  columns: ColumnDef<TData, TValue>[]
  data: TData[]
}


export function DataTable<TData, TValue>({
  columns,
  data,
  children,
  tableName
}: DataTableProps<TData, TValue> & ComponentProps<"div"> & { tableName: string }) {
  //STATE
  const [sorting, setSorting] = useState<SortingState>([])
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>(
    []
  )
  const [columnVisibility, setColumnVisibility] =
    useState<VisibilityState>({})
  //
  const pathname: Pathname = usePathname()
  const table = useReactTable({
    data,
    columns,
    enableRowSelection: true,
    enableMultiRowSelection: true,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    onSortingChange: setSorting,
    getSortedRowModel: getSortedRowModel(),
    onColumnFiltersChange: setColumnFilters,
    getFilteredRowModel: getFilteredRowModel(),
    onColumnVisibilityChange: setColumnVisibility,
    state: {
      sorting,
      columnFilters,
      columnVisibility,
    },
    //this is where you put arbitrary functions etc to make them accessible via the table api
    meta: {
      updateTextField,
      tableName,
      pathname
    }
  })




  const [filterBy, setFilterBy] = useState(table.getAllColumns()[0])
  const [isContextMenuOpen, setIsContextMenuOpen] = useState(false)
  return (<>
    <div className="flex justify-between items-center py-4">
      <div className="flex gap-2">
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="outline" className="ml-auto">
              Filter by
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            <DropdownMenuRadioGroup value={filterBy} onValueChange={setFilterBy} >
              {table
                .getAllColumns()
                .filter((column) => column.getCanFilter())
                .map((column) => {
                  return (
                    <DropdownMenuRadioItem value={column} className="capitalize" key={column.id}>
                      {column.id}
                    </DropdownMenuRadioItem>
                  )
                })}
            </DropdownMenuRadioGroup>
          </DropdownMenuContent>
        </DropdownMenu>
        <Input
          placeholder={`${filterBy.id}`}
          value={(table.getColumn(filterBy.id)?.getFilterValue() as string) ?? ""}
          onChange={(event) =>
            table.getColumn(filterBy.id)?.setFilterValue(event.target.value)
          }
          className="max-w-sm"
        />
      </div>

      {children}

      <Dialog>
        <DialogTrigger asChild>
          <Button variant="destructive" disabled={!(table.getIsSomeRowsSelected() || table.getIsAllRowsSelected())}>
            <Trash2 />
          </Button>
        </DialogTrigger>
        <DialogContent>
          <DialogHeader>
            {`Delete ${Object.keys(table.getState().rowSelection).length} ${pluralize(pathname.slice(1))}?`}
          </DialogHeader>
          <DialogDescription>
            {`Deleting ${pluralize(pathname.slice(1))} cannot be undone!`}
          </DialogDescription>
          <DialogFooter>
            <DialogClose asChild>
              <Button variant="destructive"
                onClick={() => {
                  const selectedRows = table.getState().rowSelection
                  const rowIds = Object.keys(selectedRows)
                  const recordIds = rowIds.map(id => Number(table.getRow(id).original.id))
                  console.table(recordIds)
                  deleteRecords(recordIds, pathname)
                }}>
                Yes, delete them!</Button>
            </DialogClose>
          </DialogFooter>
        </DialogContent>
      </Dialog>



      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button variant="outline" className="justify-self-end">
            <EyeIcon />
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end">
          {table
            .getAllColumns()
            .filter(
              (column) => column.getCanHide()
            )
            .map((column) => {
              return (
                <DropdownMenuCheckboxItem
                  key={column.id}
                  className="capitalize"
                  checked={column.getIsVisible()}
                  onCheckedChange={(value) =>
                    column.toggleVisibility(!!value)
                  }
                >
                  {column.id}
                </DropdownMenuCheckboxItem>
              )
            })}
        </DropdownMenuContent>
      </DropdownMenu>
    </div>
    <div className="rounded-md border">

      <Table>
        <TableHeader>
          {table.getHeaderGroups().map((headerGroup) => (
            <TableRow key={headerGroup.id}>
              {headerGroup.headers.map((header) => {
                return (
                  <TableHead key={header.id}>
                    {header.isPlaceholder
                      ? null
                      : flexRender(
                        header.column.columnDef.header,
                        header.getContext()
                      )}
                  </TableHead>
                )
              })}
            </TableRow>
          ))}
        </TableHeader>
        <TableBody>
          {table.getRowModel().rows?.length ? (
            table.getRowModel().rows.map((row) => (
              <ContextMenu onOpenChange={open => setIsContextMenuOpen(open)}>
                <ContextMenuTrigger asChild>
                  <TableRow
                    key={row.id}
                    data-state={row.getIsSelected() && "selected"}
                    tabIndex={0}
                  >
                    {row.getVisibleCells().map((cell) => (
                      <TableCell key={cell.id}>
                        {flexRender(cell.column.columnDef.cell, cell.getContext())}
                      </TableCell>
                    ))}
                    <FormContextMenu
                      row={row}
                      table={table}
                    />
                  </TableRow>
                </ContextMenuTrigger>
              </ContextMenu>
            ))
          ) : (
            <TableRow>
              <TableCell colSpan={columns.length} className="h-24 text-center">
                No results.
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </Table>
      <div className="flex items-center justify-end space-x-2 py-4">
        <Button
          variant="outline"
          size="sm"
          onClick={() => table.previousPage()}
          disabled={!table.getCanPreviousPage()}
          onBlur={true}
        >
          Previous
        </Button>
        <Button
          variant="outline"
          size="sm"
          onClick={() => table.nextPage()}
          disabled={!table.getCanNextPage()}
        >
          Next
        </Button>
      </div>
    </div>
  </>
  )
}

