'use strict';

exports.__esModule = true;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _helper = require('./Shared/helper.js');

var _Slot = require('./Shared/Slot');

var _Slot2 = _interopRequireDefault(_Slot);

var _CIcon = require('./CIcon');

var _CIcon2 = _interopRequireDefault(_CIcon);

var _CSpinner = require('./CSpinner');

var _CSpinner2 = _interopRequireDefault(_CSpinner);

var _CPagination = require('./CPagination');

var _CPagination2 = _interopRequireDefault(_CPagination);

var _CDataTableModule = require('./CDataTable.module.css');

var _CDataTableModule2 = _interopRequireDefault(_CDataTableModule);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

//component - CoreUI / CTable

var CDataTable = function CDataTable(props) {
  var children = props.children,
      innerRef = props.innerRef,
      overTableSlot = props.overTableSlot,
      columnHeaderSlot = props.columnHeaderSlot,
      sortingIconSlot = props.sortingIconSlot,
      columnFilterSlot = props.columnFilterSlot,
      detailsSlot = props.detailsSlot,
      noItemViewSlot = props.noItemViewSlot,
      captionSlot = props.captionSlot,
      underTableSlot = props.underTableSlot,
      colNameSlot = props.colNameSlot,
      fields = props.fields,
      pagination = props.pagination,
      activePage = props.activePage,
      itemsPerPage = props.itemsPerPage,
      items = props.items,
      sorter = props.sorter,
      clickableRows = props.clickableRows,
      columnFilter = props.columnFilter,
      tableFilterValue = props.tableFilterValue,
      tableFilter = props.tableFilter,
      addTableClasses = props.addTableClasses,
      size = props.size,
      dark = props.dark,
      striped = props.striped,
      fixed = props.fixed,
      hover = props.hover,
      border = props.border,
      outlined = props.outlined,
      responsive = props.responsive,
      footer = props.footer,
      itemsPerPageSelect = props.itemsPerPageSelect,
      loading = props.loading,
      change = props.change,
      onChange = props.onChange,
      customContent = props.customContent,
      attributes = _objectWithoutProperties(props, ['children', 'innerRef', 'overTableSlot', 'columnHeaderSlot', 'sortingIconSlot', 'columnFilterSlot', 'detailsSlot', 'noItemViewSlot', 'captionSlot', 'underTableSlot', 'colNameSlot', 'fields', 'pagination', 'activePage', 'itemsPerPage', 'items', 'sorter', 'clickableRows', 'columnFilter', 'tableFilterValue', 'tableFilter', 'addTableClasses', 'size', 'dark', 'striped', 'fixed', 'hover', 'border', 'outlined', 'responsive', 'footer', 'itemsPerPageSelect', 'loading', 'change', 'onChange', 'customContent']);

  //Object.assign(style, cssModule)

  var compData = (0, _react.useRef)({ firstRun: true }).current;

  // vars

  //

  var _useState = (0, _react.useState)(itemsPerPage),
      perPageItems = _useState[0],
      setPerPageItems = _useState[1];

  var _useState2 = (0, _react.useState)({
    column: null,
    asc: true
  }),
      sorterState = _useState2[0],
      setSorterState = _useState2[1];

  var _useState3 = (0, _react.useState)(tableFilterValue),
      tableFilterState = _useState3[0],
      setTableFilterState = _useState3[1];

  var _useState4 = (0, _react.useState)({}),
      columnFilterState = _useState4[0],
      setColumnFilterState = _useState4[1];

  var _useState5 = (0, _react.useState)(activePage || 1),
      page = _useState5[0],
      setPage = _useState5[1];

  var _useState6 = (0, _react.useState)(items || []),
      passedItems = _useState6[0],
      setPassedItems = _useState6[1];

  // functions

  var cellClass = function cellClass(item, colName, index) {
    var classes = [];
    if (item._cellClasses && item._cellClasses[colName]) {
      classes.push(item._cellClasses[colName]);
    }
    if (fields && fields[index]._classes) {
      classes.push(fields[index]._classes);
    }
    return classes;
  };
  var pretifyName = function pretifyName(name) {
    return name.replace(/[-_.]/g, ' ').replace(/ +/g, ' ').replace(/([a-z0-9])([A-Z])/g, '$1 $2').split(' ').map(function (word) {
      return word.charAt(0).toUpperCase() + word.slice(1);
    }).join(' ');
  };
  var headerClass = function headerClass(index) {
    //const fields = this.fields ???
    return fields && fields[index]._classes ? fields[index]._classes : '';
  };
  var isSortable = function isSortable(index) {
    return sorter && (!fields || fields[index].sorter !== false);
  };
  var headerStyles = function headerStyles(index) {
    var style = {};
    if (isSortable(index)) {
      style['cursor'] = 'pointer;';
    }
    if (fields && fields[index] && fields[index]._style) {
      var r = fields[index]._style.split(':');
      style[r[0]] = r[1].substr(0, r[1].length - 2);
    }
    return style;
  };
  var getIconState = function getIconState(index) {
    var direction = sorterState.asc ? 'asc' : 'desc';
    return rawColumnNames[index] === sorterState.column ? direction : 0;
  };
  var iconClasses = function iconClasses(index) {
    var state = getIconState(index);
    return [_CDataTableModule2.default['icon-transition position-absolute arrow-position'], !state ? _CDataTableModule2.default['transparent'] : '', state === 'desc' ? _CDataTableModule2.default['rotate-icon'] : ''];
  };
  var rowClicked = function rowClicked(item, index) {
    onChange && onChange('row-clicked', item, index);
  };
  var changeSort = function changeSort(column, index) {
    if (isSortable(index)) {
      return;
    }
    //if column changed or sort was descending change asc to true
    var state = sorterState;
    var columnRepeated = state.column === column;
    if (!sorter || !sorter.resetable) {
      state.column = column;
    } else {
      state.column = columnRepeated && state.asc === false ? null : column;
    }
    state.asc = !(columnRepeated && state.asc);
    onChange && onChange('update:sorter-value', sorterState);
  };
  var paginationChange = function paginationChange(e) {
    onChange && onChange('pagination-change', Number(e.target.value));
    setPerPageItems(Number(e.target.value));
  };
  var columnFilterEvent = function columnFilterEvent(colName, value, type) {
    var isLazy = columnFilter && columnFilter.lazy === true;
    if (isLazy && type === 'input' || !isLazy && type === 'change') {
      return;
    }
    var state = {};
    state[colName] = value;
    setColumnFilterState(_extends({}, columnFilterState, state));
    onChange && onChange('update:column-filter-value', columnFilterState);
  };
  var tableFilterChange = function tableFilterChange(value, type) {
    var isLazy = tableFilter && tableFilter.lazy === true;
    if (isLazy && type === 'input' || !isLazy && type === 'change') {
      return;
    }
    setTableFilterState(value);
    onChange && onChange('update:table-filter-value', tableFilterState);
  };

  // computed

  var generatedColumnNames = Object.keys(passedItems[0] || {}).filter(function (el) {
    return el.charAt(0) !== '_';
  });
  var rawColumnNames = function () {
    if (fields) {
      return fields.map(function (el) {
        return el.key || el;
      });
    }
    return generatedColumnNames;
  }();
  var columnFiltered = function () {
    var items = passedItems.slice();
    if (columnFilter && columnFilter.external) {
      return items;
    }
    Object.entries(columnFilterState).forEach(function (_ref) {
      var key = _ref[0],
          value = _ref[1];

      var columnFilter = String(value).toLowerCase();
      if (columnFilter && rawColumnNames.includes(key)) {
        items = items.filter(function (item) {
          return String(item[key]).toLowerCase().includes(columnFilter);
        });
      }
    });
    return items;
  }();
  var filterableCols = function () {
    return rawColumnNames.filter(function (name) {
      return generatedColumnNames.includes(name);
    });
  }();
  var tableFiltered = function () {
    var items = columnFiltered.slice();
    if (!tableFilterState || tableFilter && tableFilter.external) {
      return items;
    }
    var filter = tableFilterState.toLowerCase();
    var hasFilter = function hasFilter(item) {
      return String(item).toLowerCase().includes(filter);
    };
    items = items.filter(function (item) {
      return filterableCols.filter(function (key) {
        return hasFilter(item[key]);
      }).length;
    });
    return items;
  }();
  var sortedItems = function () {
    var col = sorterState.column;
    if (!col || !rawColumnNames.includes(col) || sorter.external) {
      return tableFiltered;
    }
    //if values in column are to be sorted by numeric value they all have to be type number
    var flip = sorterState.asc ? 1 : -1;
    return tableFiltered.slice().sort(function (a, b) {
      return a[col] > b[col] ? 1 * flip : b[col] > a[col] ? -1 * flip : 0;
    });
  }();
  var tableClasses = function () {
    var _ref2;

    return ['table', addTableClasses, (_ref2 = {}, _ref2['table-' + size] = size, _ref2['table-dark'] = dark, _ref2['table-striped'] = striped, _ref2['b-table-fixed'] = fixed, _ref2['table-hover'] = hover, _ref2['table-bordered'] = border, _ref2['border'] = outlined, _ref2)];
  }();
  var columnNames = function () {
    if (fields) {
      return fields.map(function (f) {
        return f.label !== undefined ? f.label : pretifyName(f.key || f);
      });
    }
    return rawColumnNames.map(function (el) {
      return pretifyName(el);
    });
  }();
  var sortingIconStyles = function () {
    return { 'position-relative pr-4': sorter };
  }();
  var colspan = function () {
    return rawColumnNames.length;
  }();
  var totalPages = function () {
    return Math.ceil(sortedItems.length / perPageItems) || 1;
  }();
  //
  var computedPage = pagination ? page : activePage;
  var firstItemIndex = (computedPage - 1) * perPageItems || 0;
  var paginatedItems = sortedItems.slice(firstItemIndex, firstItemIndex + perPageItems);
  var currentItems = computedPage ? paginatedItems : sortedItems;

  var tableFilterData = void 0;
  if (tableFilter) tableFilterData = {
    label: tableFilter.label || 'Filter:',
    placeholder: tableFilter.placeholder || 'type string...'

    // watch

    //itemsPerPage
  };(0, _react.useMemo)(function () {
    if (compData.firstRun) return;
    setPerPageItems(itemsPerPage);
  }, [itemsPerPage]);

  //sorterValue
  /*
  useMemo(()=>{
    const asc = sorterValue.asc === false ? false : true;
    setSorterState(Object.assign({}, { asc, column: sorterValue.column }));
  }, [sorterValue]);
  */

  //tableFilterValue
  (0, _react.useMemo)(function () {
    if (compData.firstRun) return;
    setTableFilterState(tableFilterValue);
  }, [tableFilterValue]);

  //columnFilterValue
  /*
  useMemo(()=>{
    setColumnFilterState(Object.assign({}, columnFilterValue));
  }, [columnFilterValue]);
  */

  //items
  (0, _react.useMemo)(function () {
    compData.oldItems = items;
    if (compData.firstRun) return;
    if (items.length !== compData.oldItems.length || JSON.stringify(items) !== JSON.stringify(compData.oldItems)) {
      setPassedItems(items || []);
    }
  }, [items]);

  //totalPages
  (0, _react.useMemo)(function () {
    onChange && onChange('pages-change', totalPages);
  }, [totalPages]);

  //get render par
  if (change) change();

  // render

  //custom
  //if (custom)
  //  return (<CTableCustom {...attributes} custom={customContent}>{children}</CTableCustom>);

  compData.firstRun = false;

  var scopedSlots = {}; //+

  return _react2.default.createElement(
    _react2.default.Fragment,
    null,
    _react2.default.createElement(
      'div',
      { ref: innerRef },
      itemsPerPageSelect || tableFilter ? _react2.default.createElement(
        'div',
        { className: 'row my-2 mx-0' },
        tableFilter ? _react2.default.createElement(
          'div',
          { className: 'col-sm-6 form-inline p-0' },
          _react2.default.createElement(
            'label',
            { className: 'mr-2' },
            tableFilterData.label
          ),
          _react2.default.createElement('input', {
            className: 'form-control table-filter',
            type: 'text',
            placeholder: tableFilterData.placeholder,
            onInput: function onInput(e) {
              tableFilterChange(e.target.value, 'input');
            },
            onChange: function onChange(e) {
              tableFilterChange(e.target.value, 'change');
            },
            value: tableFilterState
          })
        ) : '',
        itemsPerPageSelect ? _react2.default.createElement(
          'div',
          {
            className: 'col-sm-6 p-0' + !tableFilter ? 'offset-sm-6' : ''
          },
          _react2.default.createElement(
            'div',
            { className: 'form-inline justify-content-sm-end' },
            _react2.default.createElement(
              'label',
              { className: 'mr-2' },
              'Items per page:'
            ),
            _react2.default.createElement(
              'select',
              {
                className: 'form-control',
                onChange: paginationChange,
                value: 0
              },
              _react2.default.createElement(
                'option',
                { value: '', disabled: true, hidden: true },
                perPageItems
              ),
              [5, 10, 20, 50].map(function (number, key) {
                return _react2.default.createElement(
                  'option',
                  {
                    val: number,
                    key: key
                  },
                  number
                );
              })
            )
          )
        ) : ''
      ) : ''
    ),
    _react2.default.createElement(_Slot2.default, { content: overTableSlot }),
    _react2.default.createElement(
      'div',
      { className: 'position-relative ' + (responsive ? 'table-responsive' : '') },
      _react2.default.createElement(
        'table',
        { className: (0, _classnames2.default)(tableClasses) },
        _react2.default.createElement(
          'thead',
          null,
          _react2.default.createElement(
            'tr',
            null,
            columnNames.map(function (name, index) {
              return _react2.default.createElement(
                'th',
                {
                  onClick: function onClick() {
                    changeSort(rawColumnNames[index], index);
                  },
                  className: (0, _classnames2.default)([headerClass(index), sortingIconStyles]),
                  style: headerStyles(index),
                  key: index
                },
                _react2.default.createElement(
                  _Slot2.default,
                  { content: columnHeaderSlot['' + rawColumnNames[index]] },
                  _react2.default.createElement(
                    'div',
                    { className: 'd-inline' },
                    name
                  )
                ),
                isSortable(index) ? _react2.default.createElement(
                  _Slot2.default,
                  {
                    content: sortingIconSlot,
                    state: getIconState(index),
                    classes: iconClasses(index)
                  },
                  _react2.default.createElement(_CIcon2.default, {
                    className: (0, _classnames2.default)(iconClasses(index)),
                    width: '18',
                    content: '$options.icons.cilArrowTop',
                    name: 'cil-arrow-top'
                  })
                ) : ''
              );
            })
          ),
          columnFilter ? _react2.default.createElement(
            'tr',
            { className: 'table-sm' },
            rawColumnNames.map(function (colName, index) {
              return _react2.default.createElement(
                'th',
                { className: (0, _classnames2.default)(headerClass(index)), key: index },
                _react2.default.createElement(
                  _Slot2.default,
                  { content: columnFilterSlot['' + rawColumnNames[index]] },
                  !fields || fields[index].filter !== false ? _react2.default.createElement('input', {
                    className: 'w-100 table-filter',
                    onInput: function onInput(e) {
                      columnFilterEvent(colName, e.target.value, 'input');
                    },
                    onChange: function onChange(e) {
                      columnFilterEvent(colName, e.target.value, 'change');
                    },
                    value: columnFilterState[colName]
                  }) : ''
                )
              );
            })
          ) : ''
        ),
        _react2.default.createElement(
          'tbody',
          {
            style: clickableRows ? 'cursor:pointer;' : null,
            className: 'position-relative'
          },
          currentItems.map(function (item, itemIndex) {
            return _react2.default.createElement(
              _react2.default.Fragment,
              null,
              _react2.default.createElement(
                'tr',
                {
                  className: (0, _classnames2.default)(item._classes),
                  tabIndex: clickableRows ? 0 : null,
                  onClick: function onClick() {
                    rowClicked(item, itemIndex + firstItemIndex);
                  },
                  key: itemIndex
                },
                rawColumnNames.map(function (colName, index) {
                  if (scopedSlots[colName]) return _react2.default.createElement(_Slot2.default, {
                    content: colNameSlot,
                    item: item,
                    index: itemIndex + firstItemIndex
                  });else return _react2.default.createElement(
                    'td',
                    {
                      className: (0, _classnames2.default)(cellClass(item, colName, index)),
                      key: index
                    },
                    String(item[colName])
                  );
                })
              ),
              scopedSlots.details ? _react2.default.createElement(
                'tr',
                {
                  className: 'p-0',
                  style: { border: 'none !important' },
                  key: 'details' + itemIndex
                },
                _react2.default.createElement(
                  'td',
                  {
                    colspan: colspan,
                    className: 'p-0',
                    style: { border: 'none !important' }
                  },
                  _react2.default.createElement(_Slot2.default, {
                    content: detailsSlot,
                    item: item,
                    index: itemIndex + firstItemIndex
                  })
                )
              ) : ''
            );
          }),
          !currentItems.length ? _react2.default.createElement(
            'tr',
            null,
            _react2.default.createElement(
              'td',
              { colSpan: colspan },
              _react2.default.createElement(
                _Slot2.default,
                { content: noItemViewSlot },
                _react2.default.createElement(
                  'div',
                  { className: 'text-center my-5' },
                  _react2.default.createElement(
                    'h2',
                    null,
                    passedItems.length ? 'No filtering results ' : 'No items',
                    _react2.default.createElement(_CIcon2.default, {
                      width: '30',
                      name: 'cilBan',
                      content: '$options.icons.cilBan',
                      className: 'text-danger mb-2'
                    })
                  )
                )
              )
            )
          ) : ''
        ),
        footer && currentItems.length > 0 ? _react2.default.createElement(
          'tfoot',
          null,
          _react2.default.createElement(
            'tr',
            null,
            columnNames.map(function (name, index) {
              return _react2.default.createElement(
                'th',
                {
                  onClick: changeSort(rawColumnNames[index], index),
                  className: (0, _classnames2.default)([headerClass(index), sortingIconStyles]),
                  style: headerStyles(index),
                  key: index
                },
                _react2.default.createElement(
                  _Slot2.default,
                  { content: columnHeaderSlot['' + rawColumnNames[index]] },
                  _react2.default.createElement(
                    'div',
                    { className: 'd-inline' },
                    name
                  )
                ),
                isSortable(index) ? _react2.default.createElement(
                  _Slot2.default,
                  {
                    content: sortingIconSlot,
                    state: getIconState(index)
                  },
                  _react2.default.createElement(_CIcon2.default, {
                    width: '18',
                    name: 'cil-arrow-top',
                    content: '$options.icons.cilArrowTop',
                    className: (0, _classnames2.default)(iconClasses(index))
                  })
                ) : ''
              );
            })
          )
        ) : '',
        _react2.default.createElement(_Slot2.default, { content: captionSlot })
      ),
      loading ? _react2.default.createElement(
        _Slot2.default,
        { content: children },
        _react2.default.createElement(
          'div',
          { style: {
              position: 'absolute',
              left: '0',
              top: '0',
              bottom: '0',
              right: '0',
              backgroundColor: 'rgb(255,255,255,0.4)'
            } },
          _react2.default.createElement(
            'div',
            { style: {
                position: 'absolute',
                bottom: '50%',
                left: '50%',
                transform: 'translateX(-50%)'
              } },
            _react2.default.createElement(_CSpinner2.default, { color: 'success' })
          )
        )
      ) : ''
    ),
    _react2.default.createElement(_Slot2.default, { content: underTableSlot }),

    //:activePage.sync="page"
    pagination ? _react2.default.createElement(_CPagination2.default, {
      style: { display: totalPages > 0 ? 'inline' : 'none' },
      pages: totalPages,
      'v-bind': (typeof pagination === 'undefined' ? 'undefined' : _typeof(pagination)) === 'object' ? _extends({}, pagination) : null
    }) : ''
  );
};

CDataTable.propTypes = process.env.NODE_ENV !== "production" ? {
  tag: _helper.tagPropType,
  children: _propTypes2.default.node,
  className: _propTypes2.default.string,
  cssModule: _propTypes2.default.object,
  //custom: PropTypes.bool,
  //
  innerRef: _propTypes2.default.oneOfType([_propTypes2.default.object, _propTypes2.default.func, _propTypes2.default.string]),
  overTableSlot: _propTypes2.default.node,
  colNameSlot: _propTypes2.default.node,
  columnHeaderSlot: _propTypes2.default.array,
  sortingIconSlot: _propTypes2.default.node,
  columnFilterSlot: _propTypes2.default.node,
  detailsSlot: _propTypes2.default.node,
  noItemViewSlot: _propTypes2.default.node,
  captionSlot: _propTypes2.default.node,
  underTableSlot: _propTypes2.default.node,
  fields: _propTypes2.default.array,
  pagination: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.object]),
  activePage: _propTypes2.default.number,
  itemsPerPage: _propTypes2.default.number,
  items: _propTypes2.default.array,
  sorter: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.object]),
  clickableRows: _propTypes2.default.bool,
  columnFilter: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.object]),
  tableFilterValue: _propTypes2.default.string,
  tableFilter: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.object]),
  addTableClasses: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.array, _propTypes2.default.object]),
  size: _propTypes2.default.string,
  dark: _propTypes2.default.bool,
  striped: _propTypes2.default.bool,
  fixed: _propTypes2.default.bool,
  hover: _propTypes2.default.bool,
  border: _propTypes2.default.bool,
  outlined: _propTypes2.default.bool,
  responsive: _propTypes2.default.bool,
  footer: _propTypes2.default.bool,
  itemsPerPageSelect: _propTypes2.default.bool,
  loading: _propTypes2.default.bool,
  change: _propTypes2.default.func, //+
  onChange: _propTypes2.default.func
} : {};

CDataTable.defaultProps = {
  itemsPerPage: 10,
  responsive: true,
  columnHeaderSlot: [],
  columnFilterSlot: []
};

exports.default = CDataTable;
module.exports = exports['default'];