import 'core-js/modules/es.symbol.js';
import 'core-js/modules/es.object.get-own-property-descriptor.js';
import 'core-js/modules/es.object.get-own-property-descriptors.js';
import 'core-js/modules/es.object.keys.js';
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import get from '../../node_modules/lodash-es/get.js';
import 'core-js/modules/es.array.concat.js';
import 'core-js/modules/es.array.filter.js';
import 'core-js/modules/es.array.find.js';
import 'core-js/modules/es.array.find-index.js';
import 'core-js/modules/es.array.map.js';
import 'core-js/modules/es.array.sort.js';
import 'core-js/modules/es.object.entries.js';
import 'core-js/modules/es.object.to-string.js';
import 'core-js/modules/web.dom-collections.for-each.js';
import update from 'immutability-helper';
import { fillArrWithRowIds } from '../../utils/tableReducer.js';
import { TABLE_LOADING_SET, TABLE_ROW_EXPAND, TABLE_ROW_SELECT_ALL, TABLE_ROW_SELECT, TABLE_COLUMN_RESIZE, TABLE_COLUMN_ORDER, TABLE_COLUMN_SORT, TABLE_ROW_ACTION_ERROR, TABLE_ROW_ACTION_COMPLETE, TABLE_ROW_ACTION_EDIT, TABLE_ROW_ACTION_START, TABLE_ACTION_APPLY, TABLE_ACTION_CANCEL, TABLE_TOOLBAR_TOGGLE, TABLE_SEARCH_APPLY, TABLE_FILTER_CLEAR, TABLE_FILTER_APPLY, TABLE_PAGE_CHANGE } from './tableActionCreators.js';

function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var baseTableReducer = function baseTableReducer() {
  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  var action = arguments.length > 1 ? arguments[1] : undefined;
  // To support instance matching (i.e. multiple table states in one store), just ensure
  // that a instanceId is provided on state passed to baseTableReducer.  If no instanceId
  // is provided, all matching actions will be processed by this table reducer.
  if (typeof action.instanceId === 'string' && action.instanceId !== state.instanceId) {
    return state;
  }
  switch (action.type) {
    // Page Actions
    case TABLE_PAGE_CHANGE:
      {
        var _state$view$paginatio = state.view.pagination,
          currentPageSize = _state$view$paginatio.pageSize,
          totalItems = _state$view$paginatio.totalItems,
          currentPage = _state$view$paginatio.page;
        var _action$payload = action.payload,
          page = _action$payload.page,
          pageSize = _action$payload.pageSize;
        var isPageSizeChange = pageSize && currentPageSize !== pageSize;
        var maxPage = Math.ceil(totalItems / pageSize);
        var isPageChange = page !== currentPage && page <= maxPage;
        var newPagination = isPageSizeChange ? _objectSpread(_objectSpread(_objectSpread({}, state.view.pagination), action.payload), {}, {
          page: 1
        }) : isPageChange ? _objectSpread(_objectSpread({}, state.view.pagination), action.payload) : state.view.pagination;
        var result = update(state, {
          view: {
            pagination: {
              $set: newPagination
            }
          }
        });
        return result;
      }
    // Filter Actions
    case TABLE_FILTER_APPLY:
      {
        var newFilters = Object.entries(action.payload).map(function (_ref) {
          var _ref2 = _slicedToArray(_ref, 2),
            key = _ref2[0],
            value = _ref2[1];
          return value !== '' ? {
            columnId: key,
            value: value
          } : null;
        }).filter(function (i) {
          return i;
        });
        return update(state, {
          view: {
            filters: {
              $set: newFilters
            },
            pagination: {
              page: {
                $set: 1
              }
            }
          }
        });
      }
    case TABLE_FILTER_CLEAR:
      return update(state, {
        view: {
          filters: {
            $set: []
          },
          pagination: {
            page: {
              $set: 1
            }
          }
        }
      });
    case TABLE_SEARCH_APPLY:
      {
        var isExpanded = get(state, 'view.toolbar.search.isExpanded');
        return update(state, {
          view: {
            toolbar: {
              search: {
                $set: {
                  defaultValue: action.payload,
                  isExpanded: isExpanded
                }
              }
            },
            pagination: {
              page: {
                $set: 1
              }
            }
          }
        });
      }
    // Toolbar Actions
    case TABLE_TOOLBAR_TOGGLE:
      {
        var filterToggled = state.view.toolbar.activeBar === action.payload ? null : action.payload;
        return update(state, {
          view: {
            toolbar: {
              activeBar: {
                $set: filterToggled
              }
            }
          }
        });
      }
    // Batch Actions
    case TABLE_ACTION_CANCEL:
      return update(state, {
        view: {
          table: {
            selectedIds: {
              $set: []
            },
            isSelectAllSelected: {
              $set: false
            },
            isSelectAllIndeterminate: {
              $set: false
            }
          }
        }
      });
    case TABLE_ACTION_APPLY:
      {
        return update(state, {
          view: {
            table: {
              selectedIds: {
                $set: []
              },
              isSelectAllSelected: {
                $set: false
              },
              isSelectAllIndeterminate: {
                $set: false
              }
            }
          }
        });
      }
    // Row Actions
    case TABLE_ROW_ACTION_START:
      return update(state, {
        view: {
          table: {
            // add the in progress row
            rowActions: {
              $push: [{
                rowId: action.payload,
                isRunning: true
              }]
            }
          }
        }
      });
    case TABLE_ROW_ACTION_EDIT:
      return update(state, {
        view: {
          table: {
            // mark the row as being in edit mode
            rowActions: {
              $push: [{
                rowId: action.payload,
                isEditMode: true
              }]
            }
          }
        }
      });
    case TABLE_ROW_ACTION_COMPLETE:
      {
        var index = state.view.table.rowActions.findIndex(function (rowAction) {
          return rowAction.rowId === action.payload;
        });
        return update(state, {
          view: {
            table: {
              // remove the finished row
              rowActions: {
                $splice: [[index, 1]]
              }
            }
          }
        });
      }
    case TABLE_ROW_ACTION_ERROR:
      {
        var _index = state.view.table.rowActions.findIndex(function (rowAction) {
          return rowAction.rowId === action.payload;
        });
        return update(state, {
          view: {
            table: {
              // replace the row with the error
              rowActions: {
                $splice: [[_index, 1, {
                  rowId: action.payload,
                  error: action.error
                }]]
              }
            }
          }
        });
      }

    // Column operations
    case TABLE_COLUMN_SORT:
      {
        // TODO should check that columnId actually is valid
        var columnId = action.payload;
        var sorts = ['NONE', 'ASC', 'DESC'];
        var currentSort = state.view.table.sort;
        var isInMultiSort = Array.isArray(currentSort) && currentSort.some(function (column) {
          return column.columnId === columnId;
        });
        var currentSortDir = isInMultiSort ? currentSort.find(function (sort) {
          return sort.columnId === columnId;
        }).direction : currentSort && currentSort.columnId === columnId ? currentSort.direction : 'NONE';
        var nextSortDir = isInMultiSort ? currentSortDir === 'ASC' ? 'DESC' : 'ASC' : sorts[(sorts.findIndex(function (i) {
          return i === currentSortDir;
        }) + 1) % sorts.length];
        var sort;
        if (isInMultiSort) {
          sort = currentSort.reduce(function (carry, column) {
            if (column.columnId === columnId) {
              return [].concat(_toConsumableArray(carry), [_objectSpread(_objectSpread({}, column), {}, {
                direction: nextSortDir
              })]);
            }
            return [].concat(_toConsumableArray(carry), [column]);
          }, []);
        } else {
          sort = nextSortDir === 'NONE' ? undefined : {
            columnId: action.payload,
            direction: nextSortDir
          };
        }
        return update(state, {
          view: {
            table: {
              sort: {
                $set: sort
              }
            }
          }
        });
      }
    case TABLE_COLUMN_ORDER:
      return update(state, {
        view: {
          table: {
            ordering: {
              $set: action.payload
            }
          }
        }
      });
    case TABLE_COLUMN_RESIZE:
      return update(state, {
        columns: {
          $set: action.payload
        }
      });

    // Row operations
    case TABLE_ROW_SELECT:
      {
        var _action$payload2 = action.payload,
          selectedIds = _action$payload2.selectedIds,
          hasRowSelection = _action$payload2.hasRowSelection;
        var isMultiSelect = hasRowSelection === 'multi';
        var isClearing = isMultiSelect && selectedIds.length === 0;
        var allRowsId = [];
        var iterables = state.view.table.filteredData || state.data;
        iterables.forEach(function (row) {
          return fillArrWithRowIds(row, allRowsId);
        });
        var isSelectingAll = isMultiSelect && selectedIds.length === allRowsId.length;
        return update(state, {
          view: {
            table: {
              selectedIds: {
                $set: selectedIds
              },
              isSelectAllIndeterminate: {
                $set: !(isClearing || isSelectingAll)
              },
              isSelectAllSelected: {
                $set: isSelectingAll
              }
            }
          }
        });
      }
    case TABLE_ROW_SELECT_ALL:
      {
        var isSelected = action.payload.isSelected;
        var _selectedIds = [];
        if (isSelected) {
          var _iterables = state.view.table.filteredData || state.data;
          _iterables.forEach(function (row) {
            return fillArrWithRowIds(row, _selectedIds);
          });
        }
        return update(state, {
          view: {
            table: {
              isSelectAllSelected: {
                $set: isSelected
              },
              selectedIds: {
                $set: _selectedIds
              },
              isSelectAllIndeterminate: {
                $set: false
              }
            }
          }
        });
      }
    case TABLE_ROW_EXPAND:
      {
        var _action$payload3 = action.payload,
          rowId = _action$payload3.rowId,
          _isExpanded = _action$payload3.isExpanded,
          options = _action$payload3.options;
        return update(state, {
          view: {
            table: {
              expandedIds: {
                $set: _isExpanded ? options !== null && options !== void 0 && options.expandRowsExclusively ? [rowId] : state.view.table.expandedIds.concat([rowId]) : state.view.table.expandedIds.filter(function (i) {
                  return i !== rowId;
                })
              }
            }
          }
        });
      }
    case TABLE_LOADING_SET:
      {
        var _action$payload4 = action.payload,
          isLoading = _action$payload4.isLoading,
          rowCount = _action$payload4.rowCount;
        return update(state, {
          view: {
            table: {
              loadingState: {
                isLoading: {
                  $set: isLoading
                },
                rowCount: {
                  $set: rowCount
                }
              }
            }
          }
        });
      }
    default:
      return state;
  }
};

export { baseTableReducer };
