import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
import React, { useState, useMemo, useEffect } from 'react';
import { TableContainer, Table, Thead, Tr, Th, chakra, Box, Tbody, Td, Flex, Select, Text, Input, Checkbox } from '@chakra-ui/react';
import { TriangleUpIcon, TriangleDownIcon } from '@chakra-ui/icons';
import { getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, getFacetedRowModel, getFacetedUniqueValues, getFacetedMinMaxValues, useReactTable, flexRender } from '@tanstack/react-table';
import { FaRegMinusSquare, FaRegPlusSquare } from 'react-icons/fa';
import Empty from '../Empty/Empty.js';
import { Pagination } from '../Pagination/Pagination.js';

var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
  var target = {};
  for (var prop in source)
    if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
      target[prop] = source[prop];
  if (source != null && __getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(source)) {
      if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
        target[prop] = source[prop];
    }
  return target;
};
const dataTableMediaCSS = {
  "@media (hover: hover)": {
    ".resizer": {
      opacity: "0"
    },
    "*:hover > .resizer": {
      opacity: "1"
    }
  }
};
const dataTableResizerCSS = __spreadValues({
  content: "''",
  position: "absolute",
  right: "0",
  top: "0",
  height: "100%",
  width: "5px",
  background: "rgba(0, 0, 0, 0.5)",
  cursor: "col-resize",
  "user-select": "none",
  "touch-action": "none"
}, dataTableMediaCSS);
const isResizingCSS = {
  background: "blue",
  opacity: "1"
};
function DataTable({
  columns = [],
  data = [],
  size = "md",
  showColumnSelector = false,
  enableColumnFilters = false,
  enableColumnResizing = false,
  subComponent: SubComponent,
  expandRowByClick = false,
  selectable = false,
  rowSelection = {},
  onRowSelectionChange,
  defaultPageSize = 50,
  sorting = true,
  onSortingChange,
  pagination = true,
  onPaginationChange,
  emptyText = void 0,
  onRow = void 0,
  rowClassName = void 0,
  getRowCanExpand
}) {
  const enableSorting = sorting !== void 0 && sorting !== false;
  const expanderColumns = Boolean(SubComponent) ? [
    {
      id: "expander",
      enableSorting: false,
      cell: ({ row }) => {
        return row.getCanExpand() ? /* @__PURE__ */ jsx(
          "button",
          __spreadProps(__spreadValues({}, {
            onClick: row.getToggleExpandedHandler(),
            style: { cursor: "pointer" }
          }), {
            children: row.getIsExpanded() ? /* @__PURE__ */ jsx(FaRegMinusSquare, { size: 16 }) : /* @__PURE__ */ jsx(FaRegPlusSquare, { size: 16 })
          })
        ) : null;
      }
    }
  ] : [];
  const selectableColumns = selectable ? [
    {
      id: "select",
      header: ({ table: table2 }) => /* @__PURE__ */ jsx(
        Checkbox,
        __spreadValues({}, {
          isChecked: table2.getIsAllRowsSelected(),
          isIndeterminate: table2.getIsSomeRowsSelected(),
          onChange: table2.getToggleAllRowsSelectedHandler()
        })
      ),
      cell: ({ row }) => /* @__PURE__ */ jsx(
        Checkbox,
        __spreadValues({}, {
          isChecked: row.getIsSelected(),
          isDisabled: !row.getCanSelect(),
          isIndeterminate: row.getIsSomeSelected(),
          onChange: row.getToggleSelectedHandler()
        })
      )
    }
  ] : [];
  const [columnVisibility, setColumnVisibility] = useState({});
  const initialState = {
    pagination: {
      pageSize: -1
    }
  };
  if (pagination === true) {
    initialState.pagination = {
      pageSize: defaultPageSize,
      pageIndex: 0
    };
  } else if (pagination !== void 0 && pagination !== false) {
    initialState.pagination = pagination;
  }
  if (sorting === true) {
    initialState.sorting = [];
  } else if (sorting !== void 0 && sorting !== false) {
    initialState.sorting = sorting;
  }
  const tableOptions = {
    // Data
    data,
    columns: [...expanderColumns, ...selectableColumns, ...columns],
    initialState,
    state: {
      columnVisibility,
      rowSelection
    },
    enableSorting,
    enableColumnFilters,
    enableColumnResizing,
    onColumnVisibilityChange: setColumnVisibility,
    onRowSelectionChange,
    autoResetPageIndex: false,
    // Pipeline
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getFacetedRowModel: getFacetedRowModel(),
    getFacetedUniqueValues: getFacetedUniqueValues(),
    getFacetedMinMaxValues: getFacetedMinMaxValues(),
    //
    debugTable: true,
    getRowCanExpand: getRowCanExpand ? getRowCanExpand : () => Boolean(SubComponent)
  };
  if (pagination !== true && pagination !== void 0 && pagination !== false && onPaginationChange) {
    if (tableOptions.state) {
      tableOptions.state.pagination = pagination;
    }
    tableOptions.onPaginationChange = onPaginationChange;
  }
  if (sorting !== true && sorting !== false && sorting !== void 0 && onSortingChange) {
    if (tableOptions.state) {
      tableOptions.state.sorting = sorting;
    }
    tableOptions.onSortingChange = onSortingChange;
  }
  const table = useReactTable(tableOptions);
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(TableContainer, { children: [
    showColumnSelector && /* @__PURE__ */ jsx(ColumnSelector, { table }),
    /* @__PURE__ */ jsxs(Table, { size, variant: "simple", children: [
      /* @__PURE__ */ jsx(Thead, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx(Tr, { children: headerGroup.headers.map((header) => {
        var _a;
        return /* @__PURE__ */ jsxs(
          Th,
          {
            colSpan: header.colSpan,
            style: {
              position: "relative",
              width: header.getSize()
            },
            children: [
              header.isPlaceholder ? null : /* @__PURE__ */ jsxs(
                "div",
                __spreadProps(__spreadValues({}, {
                  className: header.column.getCanSort() ? "cursor-pointer select-none" : "",
                  onClick: header.column.getToggleSortingHandler()
                }), {
                  children: [
                    flexRender(header.column.columnDef.header, header.getContext()),
                    enableSorting && header.column.getCanSort() && /* @__PURE__ */ jsx(chakra.span, { pl: "4", children: (_a = {
                      asc: /* @__PURE__ */ jsx(TriangleUpIcon, { "aria-label": "sorted ascending" }),
                      desc: /* @__PURE__ */ jsx(TriangleDownIcon, { "aria-label": "sorted descending" })
                    }[header.column.getIsSorted()]) != null ? _a : /* @__PURE__ */ jsx(TriangleUpIcon, { "aria-label": "unsorted", color: "blackAlpha.300" }) })
                  ]
                })
              ),
              header.column.getCanFilter() ? /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ColumnFilter, { column: header.column, table }) }) : null,
              enableColumnResizing && /* @__PURE__ */ jsx(
                Box,
                __spreadProps(__spreadValues({}, {
                  onMouseDown: header.getResizeHandler(),
                  onTouchStart: header.getResizeHandler(),
                  className: `resizer ${header.column.getIsResizing() ? "isResizing" : ""}`,
                  style: {
                    transform: header.column.getIsResizing() ? `translateX(${table.getState().columnSizingInfo.deltaOffset}px)` : ""
                  }
                }), {
                  __css: header.column.getIsResizing() ? __spreadValues(__spreadValues({}, dataTableResizerCSS), isResizingCSS) : dataTableResizerCSS
                })
              )
            ]
          },
          header.id
        );
      }) }, headerGroup.id)) }),
      /* @__PURE__ */ jsx(Tbody, { children: table.getRowModel().rows.map((row) => {
        var _a;
        const subEl = (_a = SubComponent && /* @__PURE__ */ jsx(SubComponent, { row })) != null ? _a : null;
        return /* @__PURE__ */ jsxs(React.Fragment, { children: [
          /* @__PURE__ */ jsx(
            Tr,
            {
              className: rowClassName == null ? void 0 : rowClassName(row),
              onClick: expandRowByClick ? () => {
                if (row.getCanExpand()) {
                  row.toggleExpanded();
                }
              } : () => {
                onRow == null ? void 0 : onRow(row);
              },
              cursor: expandRowByClick || onRow ? "pointer" : void 0,
              children: row.getVisibleCells().map((cell) => {
                return /* @__PURE__ */ jsx(
                  Td,
                  {
                    style: {
                      width: cell.column.getSize()
                    },
                    "data-testid": "data-table-cell",
                    children: flexRender(cell.column.columnDef.cell, cell.getContext())
                  },
                  cell.id
                );
              })
            }
          ),
          row.getIsExpanded() && subEl && /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: row.getVisibleCells().length, children: subEl }) })
        ] }, row.id);
      }) })
    ] }),
    data.length === 0 && /* @__PURE__ */ jsx(Empty, { description: emptyText }),
    data.length > 0 && (typeof pagination === "object" || pagination && data.length > defaultPageSize) && /* @__PURE__ */ jsx(TablePagination, { table, size })
  ] }) });
}
function TablePagination({
  table,
  size,
  showGoToPage = false
}) {
  return /* @__PURE__ */ jsxs(Flex, { my: 4, justifyContent: "space-between", children: [
    /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
      /* @__PURE__ */ jsx(
        Select,
        {
          value: table.getState().pagination.pageSize,
          onChange: (e) => {
            table.setPageSize(Number(e.target.value));
          },
          w: "auto",
          size,
          children: [5, 10, 20, 30, 40, 50, 100].map((pageSize) => /* @__PURE__ */ jsxs("option", { value: pageSize, children: [
            pageSize,
            " / page"
          ] }, pageSize))
        }
      ),
      showGoToPage && /* @__PURE__ */ jsxs(Flex, { gap: 1, alignItems: "center", children: [
        /* @__PURE__ */ jsx(Text, { children: "Go to page:" }),
        /* @__PURE__ */ jsx(
          Input,
          {
            type: "number",
            htmlSize: 2,
            w: 100,
            onChange: (e) => {
              if (e.target.valueAsNumber) {
                table.setPageIndex(
                  Math.min(Math.max(0, e.target.valueAsNumber - 1), table.getPageCount() - 1)
                );
              }
            }
          }
        )
      ] })
    ] }),
    /* @__PURE__ */ jsx(
      Pagination,
      {
        currentPage: table.getState().pagination.pageIndex + 1,
        totalCount: table.getFilteredRowModel().rows.length,
        pageSize: table.getState().pagination.pageSize,
        onPageChange: (page) => {
          table.setPageIndex(page - 1);
        }
      }
    )
  ] });
}
function ColumnSelector({ table }) {
  return /* @__PURE__ */ jsxs("div", { className: "inline-block border border-black shadow rounded", children: [
    /* @__PURE__ */ jsx("div", { className: "px-1 border-b border-black", children: /* @__PURE__ */ jsxs("label", { children: [
      /* @__PURE__ */ jsx(
        "input",
        __spreadValues({}, {
          type: "checkbox",
          checked: table.getIsAllColumnsVisible(),
          onChange: table.getToggleAllColumnsVisibilityHandler()
        })
      ),
      " ",
      "Toggle All"
    ] }) }),
    table.getAllLeafColumns().map((column) => {
      return /* @__PURE__ */ jsx("div", { className: "px-1", children: /* @__PURE__ */ jsxs("label", { children: [
        /* @__PURE__ */ jsx(
          "input",
          __spreadValues({}, {
            type: "checkbox",
            checked: column.getIsVisible(),
            onChange: column.getToggleVisibilityHandler()
          })
        ),
        " ",
        column.id
      ] }) }, column.id);
    })
  ] });
}
function ColumnFilter({ column, table }) {
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
  const firstValue = (_a = table.getPreFilteredRowModel().flatRows[0]) == null ? void 0 : _a.getValue(column.id);
  const columnFilterValue = column.getFilterValue();
  const sortedUniqueValues = useMemo(
    () => typeof firstValue === "number" ? [] : Array.from(column.getFacetedUniqueValues().keys()).sort(),
    [column.getFacetedUniqueValues()]
  );
  return typeof firstValue === "number" ? /* @__PURE__ */ jsxs("div", { children: [
    /* @__PURE__ */ jsxs("div", { className: "flex space-x-2", children: [
      /* @__PURE__ */ jsx(
        DebouncedInput,
        {
          type: "number",
          min: Number((_c = (_b = column.getFacetedMinMaxValues()) == null ? void 0 : _b[0]) != null ? _c : ""),
          max: Number((_e = (_d = column.getFacetedMinMaxValues()) == null ? void 0 : _d[1]) != null ? _e : ""),
          value: (_f = columnFilterValue == null ? void 0 : columnFilterValue[0]) != null ? _f : "",
          onChange: (value) => column.setFilterValue((old) => [value, old == null ? void 0 : old[1]]),
          placeholder: `Min ${((_g = column.getFacetedMinMaxValues()) == null ? void 0 : _g[0]) ? `(${(_h = column.getFacetedMinMaxValues()) == null ? void 0 : _h[0]})` : ""}`,
          className: "w-24 border shadow rounded",
          w: 70
        }
      ),
      /* @__PURE__ */ jsx(
        DebouncedInput,
        {
          type: "number",
          min: Number((_j = (_i = column.getFacetedMinMaxValues()) == null ? void 0 : _i[0]) != null ? _j : ""),
          max: Number((_l = (_k = column.getFacetedMinMaxValues()) == null ? void 0 : _k[1]) != null ? _l : ""),
          value: (_m = columnFilterValue == null ? void 0 : columnFilterValue[1]) != null ? _m : "",
          onChange: (value) => column.setFilterValue((old) => [old == null ? void 0 : old[0], value]),
          placeholder: `Max ${((_n = column.getFacetedMinMaxValues()) == null ? void 0 : _n[1]) ? `(${(_o = column.getFacetedMinMaxValues()) == null ? void 0 : _o[1]})` : ""}`,
          className: "w-24 border shadow rounded",
          w: 70
        }
      )
    ] }),
    /* @__PURE__ */ jsx("div", { className: "h-1" })
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsx("datalist", { id: column.id + "list", children: sortedUniqueValues.slice(0, 5e3).map((value) => /* @__PURE__ */ jsx("option", { value }, value)) }),
    /* @__PURE__ */ jsx(
      DebouncedInput,
      {
        type: "text",
        value: columnFilterValue != null ? columnFilterValue : "",
        onChange: (value) => column.setFilterValue(value),
        placeholder: `Search... (${column.getFacetedUniqueValues().size})`,
        className: "w-36 border shadow rounded",
        list: column.id + "list"
      }
    ),
    /* @__PURE__ */ jsx("div", { className: "h-1" })
  ] });
}
function DebouncedInput(_a) {
  var _b = _a, {
    value: initialValue,
    onChange,
    debounce = 500
  } = _b, props = __objRest(_b, [
    "value",
    "onChange",
    "debounce"
  ]);
  const [value, setValue] = useState(initialValue);
  useEffect(() => {
    setValue(initialValue);
  }, [initialValue]);
  useEffect(() => {
    const timeout = setTimeout(() => {
      onChange(value);
    }, debounce);
    return () => clearTimeout(timeout);
  }, [value]);
  return /* @__PURE__ */ jsx(
    Input,
    __spreadProps(__spreadValues({}, props), {
      size: "xs",
      width: "auto",
      value,
      onChange: (e) => setValue(e.target.value)
    })
  );
}

export { DataTable as default };
//# sourceMappingURL=DataTable.js.map
