import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import { TableContainer, Table, Thead, Tr, Th, chakra, Box, Tbody, Td, Grid, Text, Flex, IconButton, InputGroup, Input, InputRightAddon, Select } from '@chakra-ui/react';
import { TriangleUpIcon, TriangleDownIcon } from '@chakra-ui/icons';
import { useState, useMemo, useEffect } from 'react';
import { CgPushChevronLeft, CgChevronLeft, CgChevronRight, CgPushChevronRight } from 'react-icons/cg';
import { useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, getFacetedRowModel, getFacetedUniqueValues, getFacetedMinMaxValues, flexRender } from '@tanstack/react-table';

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;
};
function flattenData(obj, previousKeys) {
  return Object.entries(obj).reduce(
    (flattenedData, [key, value]) => typeof value == "object" ? __spreadValues(__spreadValues({}, flattenedData), flattenData(value, previousKeys)) : __spreadProps(__spreadValues({}, flattenedData), { [`${previousKeys ? [...previousKeys, key].join(".") : key}`]: value }),
    {}
  );
}
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 = "sm",
  showPagination = false,
  showColumnSelector = false,
  enableSorting = true,
  enableColumnFilters = false,
  enableColumnResizing = false
}) {
  const [sorting, setSorting] = useState([]);
  const [visibleColumns] = useState(() => [...columns]);
  const [columnVisibility, setColumnVisibility] = useState({});
  const dataMemo = useMemo(() => data.map((item) => flattenData(item)), [flattenData, data]);
  const columnsMemo = useMemo(() => visibleColumns, []);
  const table = useReactTable({
    // Data
    data: dataMemo,
    columns: columnsMemo,
    // Functions
    state: {
      sorting,
      columnVisibility
    },
    enableSorting,
    enableColumnFilters,
    enableColumnResizing,
    onSortingChange: setSorting,
    onColumnVisibilityChange: setColumnVisibility,
    // Pipeline
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getFacetedRowModel: getFacetedRowModel(),
    getFacetedUniqueValues: getFacetedUniqueValues(),
    getFacetedMinMaxValues: getFacetedMinMaxValues(),
    //
    debugTable: true
  });
  return /* @__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 && /* @__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) => {
        return /* @__PURE__ */ jsx(Tr, { children: row.getVisibleCells().map((cell) => {
          return /* @__PURE__ */ jsx(
            Td,
            {
              style: {
                width: cell.column.getSize()
              },
              children: flexRender(cell.column.columnDef.cell, cell.getContext())
            },
            cell.id
          );
        }) }, row.id);
      }) })
    ] }),
    showPagination && /* @__PURE__ */ jsx(TablePagination, { table, size })
  ] });
}
function TablePagination({
  table,
  size,
  showTotalRows = false
}) {
  const buttonStyle = {
    size,
    variant: "ghost",
    color: "current"
  };
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Grid, { templateColumns: "1fr 2fr", mt: 4, children: [
    /* @__PURE__ */ jsx("div", { children: showTotalRows && /* @__PURE__ */ jsxs(Text, { fontSize: size, children: [
      table.getRowModel().rows.length,
      " rows"
    ] }) }),
    /* @__PURE__ */ jsxs(Flex, { alignItems: "center", justifyContent: "right", children: [
      /* @__PURE__ */ jsx(
        IconButton,
        __spreadValues({
          "aria-label": "First page",
          icon: /* @__PURE__ */ jsx(CgPushChevronLeft, {}),
          onClick: () => table.setPageIndex(0),
          disabled: !table.getCanPreviousPage()
        }, buttonStyle)
      ),
      /* @__PURE__ */ jsx(
        IconButton,
        __spreadValues({
          "aria-label": "Previous page",
          icon: /* @__PURE__ */ jsx(CgChevronLeft, {}),
          onClick: () => table.previousPage(),
          disabled: !table.getCanPreviousPage()
        }, buttonStyle)
      ),
      /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsxs(InputGroup, { size, children: [
        /* @__PURE__ */ jsx(
          Input,
          {
            type: "number",
            defaultValue: table.getState().pagination.pageIndex + 1,
            value: table.getState().pagination.pageIndex + 1,
            onChange: (e) => {
              const page = e.target.value ? Number(e.target.value) - 1 : 0;
              table.setPageIndex(page);
            },
            w: 50,
            min: 1,
            max: table.getPageCount()
          }
        ),
        /* @__PURE__ */ jsx(InputRightAddon, { children: `of ${table.getPageCount()}` })
      ] }) }),
      /* @__PURE__ */ jsx(
        IconButton,
        __spreadValues({
          "aria-label": "Next page",
          icon: /* @__PURE__ */ jsx(CgChevronRight, {}),
          onClick: () => table.nextPage(),
          disabled: !table.getCanNextPage()
        }, buttonStyle)
      ),
      /* @__PURE__ */ jsx(
        IconButton,
        __spreadValues({
          "aria-label": "Last page",
          icon: /* @__PURE__ */ jsx(CgPushChevronRight, {}),
          onClick: () => table.setPageIndex(table.getPageCount() - 1),
          disabled: !table.getCanNextPage()
        }, buttonStyle)
      ),
      /* @__PURE__ */ jsx(
        Select,
        {
          value: table.getState().pagination.pageSize,
          onChange: (e) => {
            table.setPageSize(Number(e.target.value));
          },
          w: 120,
          size,
          children: [10, 20, 30, 40, 50].map((pageSize) => /* @__PURE__ */ jsxs("option", { value: pageSize, children: [
            pageSize,
            " / page"
          ] }, pageSize))
        }
      )
    ] })
  ] }) });
}
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
