import _extends from "@babel/runtime/helpers/extends";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _defineProperty from "@babel/runtime/helpers/defineProperty";

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

/* eslint-disable max-len */
import React, { useEffect, useRef, forwardRef, useImperativeHandle } from "react";
import { useTable, usePagination, useSortBy, useRowSelect, useGlobalFilter } from "react-table";
import map from "lodash-es/map";
import split from "lodash-es/split";
import replace from "lodash-es/replace";
import merge from "lodash-es/merge";
import classnames from "classnames";
import PropTypes from "prop-types";
import CircleIcon from "@material-ui/icons/RadioButtonUnchecked";
import CheckCircleIcon from "@material-ui/icons/RadioButtonChecked";
import Paper from "@material-ui/core/Paper";
import TextField from "@material-ui/core/TextField";
import Checkbox from "@material-ui/core/Checkbox";
import Link from "../Link";
import Loading from "../Loading";
import Typography from "../Typography";
import MenuItem from "../Menu/Item";
import UpArrow from "../Icon/UpArrow";
import Plus from "../Icon/Plus";
import DownArrow from "../Icon/DownArrow";
import ChevronRight from "../Icon/ChevronRight";
import Skeleton from "../Skeleton";
import Pagination from "./Pagination";
import getClasses from "./styles";

function printHeaderDefault(value) {
  return value;
}

function printBodyDefault(value) {
  return value;
}

function rowFilterDefault(rows) {
  return rows;
} // When the useGlobalFilter hook is used, the rows, rowsById and flatRows properties of instance (the object we obtain with the useTable hook)
// are replaced with the filtered data.
// With this hook those properties remains unchanged so, for example, it is possible to deselect all rows
// no matter what filter is applied (For instance, toggleAllRowsSelected is applied to the rows property, that's why this change is needed)


function useCorrectRowDataInstance(hooks) {
  function useInstance(instance) {
    Object.assign(instance, {
      rows: instance.preGlobalFilteredRows,
      rowsById: instance.preGlobalFilteredRowsById,
      flatRows: instance.preGlobalFilteredFlatRows
    });
  }

  hooks.useInstance.push(useInstance);
}

var TableBase = /*#__PURE__*/forwardRef(function (props, ref) {
  var _classnames;

  var headers = props.headers,
      data = props.data,
      sortingIconsColors = props.sortingIconsColors,
      showEntries = props.showEntries;
  var pagination = props.pagination,
      entriesNumber = props.entriesNumber,
      entriesOptions = props.entriesOptions,
      entriesText = props.entriesText;
  var previousText = props.previousText,
      nextText = props.nextText,
      resultsText = props.resultsText,
      printBody = props.printBody;
  var selection = props.selection,
      selectionCallback = props.selectionCallback,
      sortCallback = props.sortCallback,
      fullWidth = props.fullWidth,
      disableSortRemove = props.disableSortRemove;
  var autoResetSortBy = props.autoResetSortBy,
      defaultSorting = props.defaultSorting,
      rowFilterCallback = props.rowFilterCallback,
      autoResetPage = props.autoResetPage,
      filterDataCallback = props.filterDataCallback;
  var enableSelectAllRows = props.enableSelectAllRows,
      createRow = props.createRow,
      disableSort = props.disableSort;
  var classes = getClasses({
    sortingIconsColors: sortingIconsColors
  });
  var customColumns = {};
  headers.forEach(function (header) {
    customColumns = _objectSpread(_objectSpread({}, customColumns), {}, _defineProperty({}, header.accessor, !!header.custom));
  });
  headers.forEach(function (header, idx) {
    headers[idx] = _objectSpread({
      sortType: "basic"
    }, headers[idx]);
  });
  var newClasses = props.classes;
  var didMount = useRef(false);

  var _useTable = useTable({
    columns: headers,
    data: data,
    PaginationComponent: Pagination,
    initialState: {
      pageIndex: 0,
      pageSize: entriesNumber,
      sortBy: defaultSorting,
      // If state.globalFilter is undefined, the function rowFilterCallback will never be executed
      globalFilter: {}
    },
    autoResetSelectedRows: false,
    disableSortRemove: disableSortRemove,
    autoResetSortBy: autoResetSortBy,
    globalFilter: rowFilterCallback,
    autoResetPage: autoResetPage // manualPagination: true,
    // manualSortBy: !!sortCallback,

  }, useGlobalFilter, useSortBy, usePagination, useCorrectRowDataInstance, selection && useRowSelect, function (hooks) {
    if (selection) {
      hooks.visibleColumns.push(function (columns) {
        return [// Let's make a column for selection
        {
          id: "selection",
          // The header can use the table's getToggleAllRowsSelectedProps method
          // to render a checkbox
          Header: function Header(_ref) {
            var getToggleAllPageRowsSelectedProps = _ref.getToggleAllPageRowsSelectedProps,
                getToggleAllRowsSelectedProps = _ref.getToggleAllRowsSelectedProps;
            var selectFunctionProps = enableSelectAllRows ? getToggleAllRowsSelectedProps : getToggleAllPageRowsSelectedProps;
            return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Checkbox, _extends({
              icon: /*#__PURE__*/React.createElement(CircleIcon, {
                className: newClasses.headerSelectionIcon
              }),
              checkedIcon: /*#__PURE__*/React.createElement(CheckCircleIcon, {
                className: newClasses.headerSelectionIcon
              })
            }, selectFunctionProps())));
          },
          // The cell can use the individual row's getToggleRowSelectedProps method
          // to the render a checkbox
          Cell: function Cell(_ref2) {
            var row = _ref2.row;

            if (row.original._isLoading) {
              return /*#__PURE__*/React.createElement(Skeleton, null);
            }

            ;
            return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Checkbox, _extends({
              icon: /*#__PURE__*/React.createElement(CircleIcon, {
                className: classes.selectionIcon
              }),
              checkedIcon: /*#__PURE__*/React.createElement(CheckCircleIcon, {
                className: classes.selectionIcon
              })
            }, row.getToggleRowSelectedProps())));
          }
        }].concat(_toConsumableArray(columns));
      });
    }
  }),
      getTableProps = _useTable.getTableProps,
      getTableBodyProps = _useTable.getTableBodyProps,
      headerGroups = _useTable.headerGroups,
      prepareRow = _useTable.prepareRow,
      page = _useTable.page,
      pageCount = _useTable.pageCount,
      gotoPage = _useTable.gotoPage,
      setPageSize = _useTable.setPageSize,
      selectedFlatRows = _useTable.selectedFlatRows,
      toggleAllRowsSelected = _useTable.toggleAllRowsSelected,
      toggleAllPageRowsSelected = _useTable.toggleAllPageRowsSelected,
      _useTable$state = _useTable.state,
      pageIndex = _useTable$state.pageIndex,
      pageSize = _useTable$state.pageSize,
      sortBy = _useTable$state.sortBy,
      globalFilteredRows = _useTable.globalFilteredRows,
      sortedRows = _useTable.sortedRows,
      setGlobalFilter = _useTable.setGlobalFilter; // Force an update when the filterCallback changes to put reset the pagination


  useEffect(function () {
    setGlobalFilter([]);
  }, [setGlobalFilter, rowFilterCallback]);
  useEffect(function () {
    filterDataCallback(_toConsumableArray(globalFilteredRows));
  }, [filterDataCallback, globalFilteredRows]);
  useEffect(function () {
    if (didMount.current) selectionCallback(selectedFlatRows.filter(function (cell) {
      return !cell.original._isLoading;
    }));else didMount.current = true;
  }, [selectedFlatRows, selectionCallback]);
  useEffect(function () {
    if (!!sortCallback && !!sortBy[0]) sortCallback(sortBy[0].id, sortBy[0].desc);
  }, [sortCallback, sortBy]);

  var getSortIcon = function getSortIcon(column) {
    if (disableSort) return null;

    if (column.isSorted) {
      if (column.isSortedDesc) {
        return /*#__PURE__*/React.createElement("span", {
          className: classes.sortIcons
        }, /*#__PURE__*/React.createElement(UpArrow, {
          className: classes.arrow,
          size: 14
        }), /*#__PURE__*/React.createElement(DownArrow, {
          className: classnames(classes.arrow, classes.activeArrow),
          size: 14
        }));
      }

      return /*#__PURE__*/React.createElement("span", {
        className: classes.sortIcons
      }, /*#__PURE__*/React.createElement(UpArrow, {
        className: classnames(classes.arrow, classes.activeArrow),
        size: 14
      }), /*#__PURE__*/React.createElement(DownArrow, {
        className: classes.arrow,
        size: 14
      }));
    }

    return /*#__PURE__*/React.createElement("span", {
      className: classes.sortIcons
    }, /*#__PURE__*/React.createElement(UpArrow, {
      className: classes.arrow,
      size: 14
    }), /*#__PURE__*/React.createElement(DownArrow, {
      className: classes.arrow,
      size: 14
    }));
  };

  var entries = pagination ? page : sortedRows;
  useImperativeHandle(ref, function () {
    return {
      // methods that can be used in parent
      checkAllRows: function checkAllRows(mode) {
        // true => checkAll, false => uncheckAll
        toggleAllRowsSelected(mode);
      },
      checkAllPageRows: function checkAllPageRows(mode) {
        // true => checkAll, false => uncheckAll
        toggleAllPageRowsSelected(mode);
      }
    };
  });

  var isClickable = function isClickable(target) {
    return ["BUTTON", "A", "INPUT", "TEXTAREA", "SUMMARY", "SELECT", "OPTION"].includes(target.tagName);
  };

  var hasTextSelected = function hasTextSelected() {
    var cellText = document.getSelection();
    return cellText.type === "Range";
  };

  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: fullWidth ? "block" : "flex"
    }
  }, /*#__PURE__*/React.createElement("div", null, (pagination && showEntries || showEntries) && /*#__PURE__*/React.createElement("div", {
    className: classes.entriesWrapper
  }, /*#__PURE__*/React.createElement(Typography, null, split(entriesText, "--entries--")[0]), /*#__PURE__*/React.createElement(TextField, {
    value: pageSize,
    onChange: function onChange(e) {
      setPageSize(Number(e.target.value));
    },
    InputProps: {
      classes: {
        root: classes.inputBase
      }
    },
    InputLabelProps: {
      classes: {
        root: classes.labelRoot
      }
    },
    variant: "outlined",
    SelectProps: {
      classes: {
        icon: classes.selectIcon,
        root: classes.selectRoot
      },
      MenuProps: {
        classes: {
          paper: classes.scroll
        }
      },
      IconComponent: ChevronRight
    },
    className: classes.entriesSelect,
    select: true
  }, map(entriesOptions, function (option) {
    return /*#__PURE__*/React.createElement(MenuItem, {
      className: classes.menuItem,
      key: "entries-".concat(option),
      value: option
    }, option);
  })), /*#__PURE__*/React.createElement(Typography, null, split(entriesText, "--entries--")[1])), /*#__PURE__*/React.createElement(Paper, {
    className: !!newClasses && newClasses.paper ? classnames(classes.paper, newClasses.paper, classes.scrollBar) : classnames(classes.paper, classes.scrollBar),
    elevation: 0
  }, /*#__PURE__*/React.createElement("table", _extends({}, getTableProps(), {
    className: !!newClasses && newClasses.table ? newClasses.table : ""
  }), /*#__PURE__*/React.createElement("thead", {
    className: !!newClasses && newClasses.header ? newClasses.header : ""
  }, headerGroups.map(function (headerGroup) {
    return /*#__PURE__*/React.createElement("tr", _extends({}, headerGroup.getHeaderGroupProps(), {
      className: classes.headerRow
    }), headerGroup.headers.map(function (column) {
      var _column$fixedWidth, _column$align;

      return /*#__PURE__*/React.createElement("th", merge(column.getHeaderProps(!disableSort && column.getSortByToggleProps()), {
        style: {
          width: (_column$fixedWidth = column.fixedWidth) !== null && _column$fixedWidth !== void 0 ? _column$fixedWidth : "",
          textAlign: (_column$align = column.align) !== null && _column$align !== void 0 ? _column$align : ""
        },
        className: classes.headerCell
      }), column.render("Header"), column.id !== "selection" && !column.hideSort && getSortIcon(column));
    }));
  })), /*#__PURE__*/React.createElement("tbody", _extends({}, getTableBodyProps(), {
    className: !!newClasses && !!newClasses.tableBody ? newClasses.tableBody : ""
  }), createRow.callback && /*#__PURE__*/React.createElement("tr", {
    className: !!newClasses && !!newClasses.row ? newClasses.row : ""
  }, /*#__PURE__*/React.createElement("td", {
    colSpan: "20",
    style: {
      width: "",
      overflowWrap: "",
      textAlign: ""
    },
    className: classnames((_classnames = {}, _defineProperty(_classnames, classes.bodyCell, true), _defineProperty(_classnames, newClasses.cell, !!(newClasses !== null && newClasses !== void 0 && newClasses.cell)), _classnames))
  }, /*#__PURE__*/React.createElement(Link, {
    onClick: createRow.callback,
    disabled: createRow.loading,
    className: classes.loading
  }, createRow.loading && /*#__PURE__*/React.createElement(Loading, {
    size: 14,
    color: "primary",
    className: classes.newRowIcon
  }), /*#__PURE__*/React.createElement(Typography, {
    color: "primary",
    variant: "f1-14"
  }, !createRow.loading && /*#__PURE__*/React.createElement(Plus, {
    size: 14,
    color: "primary",
    className: classes.newRowIcon
  }), createRow.label)))), entries.map(function (row) {
    prepareRow(row);

    var getCellValue = function getCellValue(cell) {
      if (cell.row.original._isLoading) {
        return /*#__PURE__*/React.createElement(Skeleton, null);
      }

      if (customColumns[cell.column.id]) {
        return printBody(cell.value, cell.column.id, cell.row.id);
      }

      if (typeof cell.value === "number") {
        return /*#__PURE__*/React.createElement(Typography, {
          align: "right"
        }, cell.render("Cell"));
      }

      if (typeof cell.value === "string") {
        return /*#__PURE__*/React.createElement(Typography, {
          align: "left"
        }, cell.render("Cell"));
      }

      return cell.render("Cell");
    };

    var handleClick = function handleClick(ev) {
      if (isClickable(ev.target)) return;
      if (hasTextSelected()) return;
      row.toggleRowSelected();
    };

    return /*#__PURE__*/React.createElement("tr", _extends({}, row.getRowProps(), {
      className: !!newClasses && !!newClasses.row ? newClasses.row : ""
    }, selection && !row.original._isLoading && {
      onClick: handleClick
    }), row.cells.map(function (cell) {
      var _cell$column$fixedWid, _cell$column$align, _classnames2;

      return /*#__PURE__*/React.createElement("td", cell.getCellProps({
        style: {
          width: (_cell$column$fixedWid = cell.column.fixedWidth) !== null && _cell$column$fixedWid !== void 0 ? _cell$column$fixedWid : "",
          overflowWrap: cell.column.fixedWidth ? "anywhere" : "",
          textAlign: (_cell$column$align = cell.column.align) !== null && _cell$column$align !== void 0 ? _cell$column$align : ""
        },
        className: classnames((_classnames2 = {}, _defineProperty(_classnames2, classes.bodyCell, true), _defineProperty(_classnames2, newClasses.cell, !!(newClasses !== null && newClasses !== void 0 && newClasses.cell)), _classnames2))
      }), getCellValue(cell));
    }));
  })))), pagination && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Typography, {
    className: classes.results,
    align: "center"
  }, replace(replace(resultsText, "--total--", globalFilteredRows.length), "--number--", entries.length)), /*#__PURE__*/React.createElement(Pagination, {
    pages: pageCount,
    page: pageIndex,
    onPageChange: gotoPage,
    previousText: previousText,
    nextText: nextText
  }))));
});
TableBase.propTypes = {
  headers: PropTypes.instanceOf(Array).isRequired,
  data: PropTypes.instanceOf(Array).isRequired,
  customColumns: PropTypes.instanceOf(Array),
  sortingIconsColors: PropTypes.instanceOf(Object),
  pagination: PropTypes.bool,
  fullWidth: PropTypes.bool,
  showEntries: PropTypes.bool,
  entriesNumber: PropTypes.number,
  entriesOptions: PropTypes.instanceOf(Array),
  entriesText: PropTypes.string,
  // Text in select
  resultsText: PropTypes.string,
  // Text below the table
  previousText: PropTypes.string,
  nextText: PropTypes.string,
  printHeader: PropTypes.func,
  printBody: PropTypes.func,
  selectionCallback: PropTypes.func,
  selectAllRows: PropTypes.func,
  selectAllPages: PropTypes.func,
  sortCallback: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
  disableSortRemove: PropTypes.bool,
  autoResetSortBy: PropTypes.bool,
  defaultSorting: PropTypes.arrayOf(PropTypes.shape({
    id: PropTypes.string.isRequired,
    desc: PropTypes.bool
  })),
  rowFilterCallback: PropTypes.func,
  autoResetPage: PropTypes.bool,
  filterDataCallback: PropTypes.func,
  enableSelectAllRows: PropTypes.bool,
  createRow: PropTypes.shape({
    callback: PropTypes.func,
    label: PropTypes.string,
    loading: PropTypes.bool
  }),
  disableSort: PropTypes.bool
};
TableBase.defaultProps = {
  customColumns: [],
  sortingIconsColors: {
    defaultColor: {
      color: "neutral",
      shade: 500
    },
    activeArrow: {
      color: "primary",
      shade: 900
    }
  },
  pagination: true,
  showEntries: true,
  entriesNumber: 10,
  entriesOptions: [10, 20, 30, 40, 50],
  previousText: "Previous",
  nextText: "Next",
  entriesText: "Show --entries-- entries",
  resultsText: "Showing --number-- of --total-- results",
  printHeader: printHeaderDefault,
  printBody: printBodyDefault,
  selectionCallback: function selectionCallback() {},
  selectAllRows: function selectAllRows() {},
  selectAllPages: function selectAllPages() {},
  sortCallback: false,
  fullWidth: false,
  disableSortRemove: false,
  autoResetSortBy: true,
  defaultSorting: [],
  rowFilterCallback: rowFilterDefault,
  autoResetPage: true,
  filterDataCallback: function filterDataCallback() {},
  enableSelectAllRows: false,
  createRow: {
    callback: undefined,
    label: "New row",
    loading: false
  },
  disableSort: false
};
export default TableBase;