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; };

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; }

import React, { useState, useEffect, useRef, useMemo } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { tagPropType, mapToCssModules } from './Shared/helper.js';
import Slot from './Shared/Slot';
import CIcon from './CIcon';
import CSpinner from './CSpinner';
import CPagination from './CPagination';
import style from './CDataTable.module.css';

//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 = useRef({ firstRun: true }).current;

  // vars

  //

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

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

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

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

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

  var _useState6 = 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 [style['icon-transition position-absolute arrow-position'], !state ? style['transparent'] : '', state === 'desc' ? style['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
  };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
  useMemo(function () {
    if (compData.firstRun) return;
    setTableFilterState(tableFilterValue);
  }, [tableFilterValue]);

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

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

    //:activePage.sync="page"
    pagination ? React.createElement(CPagination, {
      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: tagPropType,
  children: PropTypes.node,
  className: PropTypes.string,
  cssModule: PropTypes.object,
  //custom: PropTypes.bool,
  //
  innerRef: PropTypes.oneOfType([PropTypes.object, PropTypes.func, PropTypes.string]),
  overTableSlot: PropTypes.node,
  colNameSlot: PropTypes.node,
  columnHeaderSlot: PropTypes.array,
  sortingIconSlot: PropTypes.node,
  columnFilterSlot: PropTypes.node,
  detailsSlot: PropTypes.node,
  noItemViewSlot: PropTypes.node,
  captionSlot: PropTypes.node,
  underTableSlot: PropTypes.node,
  fields: PropTypes.array,
  pagination: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
  activePage: PropTypes.number,
  itemsPerPage: PropTypes.number,
  items: PropTypes.array,
  sorter: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
  clickableRows: PropTypes.bool,
  columnFilter: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
  tableFilterValue: PropTypes.string,
  tableFilter: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
  addTableClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.array, PropTypes.object]),
  size: PropTypes.string,
  dark: PropTypes.bool,
  striped: PropTypes.bool,
  fixed: PropTypes.bool,
  hover: PropTypes.bool,
  border: PropTypes.bool,
  outlined: PropTypes.bool,
  responsive: PropTypes.bool,
  footer: PropTypes.bool,
  itemsPerPageSelect: PropTypes.bool,
  loading: PropTypes.bool,
  change: PropTypes.func, //+
  onChange: PropTypes.func
} : {};

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

export default CDataTable;