"use client";

import { useMemo } from "react";
import { useDataTable } from "../../hooks/useDataTable";
import { TableHeader } from "./core/TableHeader";
import { TableBody } from "./core/TableBody";
import { TablePagination } from "./core/TablePagination";
import { TableLoading } from "./core/TableLoading";
import { TableEmpty } from "./core/TableEmpty";
import { tableVariants } from "./styles/variants";
import { DataTableProps } from "../../types/table.types";

const mergeClasses = (...classes: Array<string | undefined>) =>
  classes.filter(Boolean).join(" ");

export function DataTable<TData extends object>({
  data,
  columns,
  selectable = false,
  loading = false,
  toolbar,
  filters,
  emptyState,
  appearance = "default",
  size = "md",
  classNames,
  pagination,
  sorting,
  rowSelection,
  onRowSelectionChange,
  onSelectedRowsChange,
  getRowId,
}: DataTableProps<TData>) {
  const table = useDataTable<TData>({
    data,
    columns,
    selectable,
    pagination,
    sorting,
    rowSelection,
    onRowSelectionChange,
    onSelectedRowsChange,
    getRowId,
  });

  const variantStyles = useMemo(
    () => ({
      root: mergeClasses(
        // tableVariants.appearance[appearance].root,
        classNames?.root,
      ),

      table: mergeClasses(
        // tableVariants.appearance[appearance].table,
        classNames?.table,
      ),

      tableThead: mergeClasses(
        // tableVariants.appearance[appearance].tableThead,
        classNames?.tableThead,
      ),

      tableTheadRow: mergeClasses(
        // tableVariants.appearance[appearance].tableTheadRow,
        classNames?.tableTheadRow,
      ),

      tableTheadCell: mergeClasses(
        // tableVariants.appearance[appearance].tableTheadCell,
        tableVariants.size[size].tableTheadCell,
        classNames?.tableTheadCell,
      ),

      tableTbody: mergeClasses(
        // tableVariants.appearance[appearance].tableTbody,
        classNames?.tableTbody,
      ),

      tableTbodyRow: mergeClasses(
        // tableVariants.appearance[appearance].tableTbodyRow,
        tableVariants.size[size].tableTbodyRow,
        classNames?.tableTbodyRow,
      ),

      tableTbodyCell: mergeClasses(
        // tableVariants.appearance[appearance].tableTbodyCell,
        tableVariants.size[size].tableTbodyCell,
        classNames?.tableTbodyCell,
      ),

      pagination: mergeClasses(
        // tableVariants.appearance[appearance].pagination,
        classNames?.pagination,
      ),

      toolbar: classNames?.toolbar,

      filters: classNames?.filters,
    }),
    [appearance, size, classNames],
  );

  const hasRows = table.getRowModel().rows.length > 0;

  return (
    <div className={variantStyles.root}>
      {(toolbar || filters) && (
        <div
          className={`flex gap-3 pb-3 2xl:pb-5 flex-wrap items-center ${
            toolbar ? "justify-between" : "sm:justify-end"
          }`}
        >
          {toolbar && <div className={variantStyles.toolbar}>{toolbar}</div>}
          {filters && <div className={variantStyles.filters}>{filters}</div>}
        </div>
      )}

      <div className=" overflow-x-auto">
        <table className={`${variantStyles.table} min-w-full table-fixed`}>
          <TableHeader<TData>
            table={table}
            classNames={{
              tableThead: variantStyles.tableThead,
              tableTheadRow: variantStyles.tableTheadRow,
              tableTheadCell: variantStyles.tableTheadCell,
            }}
          />

          {loading ? (
            <tbody>
              <tr>
                <td colSpan={columns.length + (selectable ? 1 : 0)}>
                  <TableLoading />
                </td>
              </tr>
            </tbody>
          ) : hasRows ? (
            <TableBody<TData>
              table={table}
              classNames={{
                tableTbody: variantStyles.tableTbody,
                tableTbodyRow: variantStyles.tableTbodyRow,
                tableTbodyCell: variantStyles.tableTbodyCell,
              }}
            />
          ) : (
            <tbody>
              <tr>
                <td colSpan={columns.length + (selectable ? 1 : 0)}>
                  <TableEmpty emptyState={emptyState} />
                </td>
              </tr>
            </tbody>
          )}
        </table>
      </div>

      {!loading && hasRows && (
        <TablePagination
          pagination={pagination}
          className={variantStyles.pagination}
        />
      )}
    </div>
  );
}
