import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { connect } from 'react-redux';
import { ALL_PAGES, createRegExp } from './utils';
export var highlight = function highlight(str, filter) {
  if (str === void 0) {
    str = '';
  }

  if (filter === void 0) {
    filter = '';
  }

  return str.toString().replace(createRegExp(filter), '<strong>$1</strong>');
};
var _highlight = highlight;
export var Highlight = function Highlight(_ref) {
  var children = _ref.children,
      filter = _ref.filter,
      highlight = _ref.highlight,
      props = _objectWithoutPropertiesLoose(_ref, ["children", "filter", "highlight"]);

  var hl = highlight || _highlight;
  return React.createElement("span", _extends({}, props, {
    dangerouslySetInnerHTML: {
      __html: hl(children, filter)
    }
  }));
};
Highlight.propTypes = {
  children: PropTypes.node,
  filter: PropTypes.string,
  highlight: PropTypes.func
};
Highlight.defaultProps = {
  children: null,
  filter: '',
  highlight: null
};
export var TH = function TH(_ref2) {
  var _ref2$sort = _ref2.sort,
      by = _ref2$sort.by,
      reverse = _ref2$sort.reverse,
      onSetSort = _ref2.onSetSort,
      nextBy = _ref2.by,
      children = _ref2.children,
      className = _ref2.className,
      props = _objectWithoutPropertiesLoose(_ref2, ["sort", "onSetSort", "by", "children", "className"]);

  var isCurrent = nextBy === by; //TODO Add ability to customize onClick

  var onClick = function onClick(e) {
    e.preventDefault();
    onSetSort(nextBy, isCurrent ? !reverse : false);
  };

  className = classnames('sortable', {
    'order-asc': isCurrent && !reverse,
    'order-desc': isCurrent && reverse
  }, className);
  var iconClassName = classnames('rc-icon', isCurrent && reverse ? 'rc-icon-chevron-up-small' : 'rc-icon-chevron-down-small', 'sorter-icon', {
    'list-hover-arrow': !isCurrent
  });
  return React.createElement("th", _extends({
    onClick: onClick
  }, props, {
    className: className
  }), children, React.createElement("span", {
    className: classnames(iconClassName)
  }));
};
TH.propTypes = {
  children: PropTypes.node,
  sort: PropTypes.shape({
    by: PropTypes.string.isRequired,
    reverse: PropTypes.bool.isRequired
  }),
  by: PropTypes.string.isRequired,
  className: PropTypes.string,
  onSetSort: PropTypes.func.isRequired
};
TH.defaultProps = {
  children: null,
  sort: null,
  className: null
};
export var Pagination = function Pagination(_ref3) {
  var loading = _ref3.loading,
      filteredTotal = _ref3.filteredTotal,
      _ref3$pagination = _ref3.pagination,
      page = _ref3$pagination.page,
      perPage = _ref3$pagination.perPage,
      onSetPage = _ref3.onSetPage,
      className = _ref3.className,
      props = _objectWithoutPropertiesLoose(_ref3, ["loading", "filteredTotal", "pagination", "onSetPage", "className"]);

  var onPageClick = function onPageClick(p, e) {
    e.preventDefault();
    onSetPage(p);
  };

  var totalPages = Math.ceil(filteredTotal / perPage);
  var pages = [];

  for (var i = 1; i < totalPages + 1; i++) {
    pages.push(React.createElement("button", {
      className: classnames('btn btn-default', {
        active: page === i
      }),
      key: i,
      onClick: onPageClick.bind(null, i),
      disabled: loading
    }, i));
  }

  return React.createElement("span", _extends({
    className: classnames('btn-group', className)
  }, props), pages);
};
Pagination.propTypes = {
  pagination: PropTypes.shape({
    page: PropTypes.number.isRequired,
    perPage: PropTypes.number.isRequired
  }).isRequired,
  loading: PropTypes.bool,
  filteredTotal: PropTypes.number.isRequired,
  className: PropTypes.string,
  onSetPage: PropTypes.func.isRequired
};
Pagination.defaultProps = {
  loading: false,
  className: null
};
export var PerPageSelector = function PerPageSelector(_ref4) {
  var loading = _ref4.loading,
      _ref4$pagination = _ref4.pagination,
      perPage = _ref4$pagination.perPage,
      availablePerPage = _ref4$pagination.availablePerPage,
      onSetPerPage = _ref4.onSetPerPage,
      props = _objectWithoutPropertiesLoose(_ref4, ["loading", "pagination", "onSetPerPage"]);

  var onChange = function onChange(e) {
    onSetPerPage(parseInt(e.target.value, 10));
  };

  return React.createElement("select", _extends({
    className: "form-control",
    onChange: onChange,
    value: perPage,
    disabled: loading
  }, props), availablePerPage.map(function (p, i) {
    return React.createElement("option", {
      key: i,
      value: p
    }, p === ALL_PAGES ? 'All' : p);
  }));
};
PerPageSelector.propTypes = {
  pagination: PropTypes.shape({
    availablePerPage: PropTypes.arrayOf(PropTypes.number).isRequired,
    perPage: PropTypes.number.isRequired
  }).isRequired,
  loading: PropTypes.bool,
  onSetPerPage: PropTypes.func.isRequired
};
PerPageSelector.defaultProps = {
  loading: false
};
/**
 * @param {Setup} setup
 * @param {function} [propsMapper]
 * @param {function} [dispatchMapper]
 * @return {function(*)}
 */

export var connectSetup = function connectSetup(setup, propsMapper, dispatchMapper) {
  if (propsMapper === void 0) {
    propsMapper = function propsMapper(props) {
      return props;
    };
  }

  if (dispatchMapper === void 0) {
    dispatchMapper = function dispatchMapper(props) {
      return props;
    };
  }

  return function (Cmp) {
    if (!propsMapper) {
      propsMapper = function propsMapper(props) {
        return props;
      };
    }

    if (!dispatchMapper) {
      dispatchMapper = function dispatchMapper(props) {
        return props;
      };
    }

    return connect(function (state) {
      return propsMapper({
        filter: setup.getFilter(state),
        fetched: setup.getFetched(state),
        loading: setup.getLoading(state),
        error: setup.getError(state),
        items: setup.getItems(state),
        total: setup.getTotal(state),
        filteredTotal: setup.getFilteredTotal(state),
        sort: setup.getSort(state),
        pagination: setup.getPagination(state),
        params: setup.getParams(state),
        setup: setup //TODO Unnecessary?

      }, setup);
    }, dispatchMapper({
      onLoad: setup.load,
      onSetParams: setup.setParams,
      onSetSort: setup.setSort,
      onSetPage: setup.setPage,
      onSetPerPage: setup.setPerPage,
      onSetFilter: setup.setFilter
    }, setup))(Cmp);
  };
};
/**
 * @param {Setup} setup
 * @param {function} [mapper]
 * @return {function(*)}
 */

export var connectUI = function connectUI(setup, mapper) {
  if (mapper === void 0) {
    mapper = function mapper(props) {
      return props;
    };
  }

  var UI = mapper({
    TH: connectSetup(setup)(TH),
    Highlight: connectSetup(setup)(Highlight),
    PerPageSelector: connectSetup(setup)(PerPageSelector),
    Pagination: connectSetup(setup)(Pagination)
  }, setup);
  return function (Cmp) {
    return function (props) {
      return React.createElement(Cmp, _extends({}, props, UI));
    };
  };
};
export var SetupContext =
/*#__PURE__*/
function (_React$Component) {
  _inheritsLoose(SetupContext, _React$Component);

  function SetupContext() {
    return _React$Component.apply(this, arguments) || this;
  }

  var _proto = SetupContext.prototype;

  _proto.getChildContext = function getChildContext() {
    return {
      setup: this.props.setup //TODO Multiple named setups via this.props.setup.prefix()

    };
  };

  _proto.render = function render() {
    return this.props.children;
  };

  return SetupContext;
}(React.Component);

_defineProperty(SetupContext, "propTypes", {
  setup: PropTypes.any.isRequired,
  children: PropTypes.any.isRequired
});

_defineProperty(SetupContext, "childContextTypes", {
  setup: PropTypes.any
});

export var ContextChild =
/*#__PURE__*/
function (_React$Component2) {
  _inheritsLoose(ContextChild, _React$Component2);

  function ContextChild() {
    return _React$Component2.apply(this, arguments) || this;
  }

  var _proto2 = ContextChild.prototype;

  _proto2.componentWillMount = function componentWillMount() {
    this.component = this.connectComponent();
  }
  /**
   * @abstract
   * @return {React.Component}
   */
  ;

  _proto2.getComponent = function getComponent() {
    return null;
  };

  _proto2.connectComponent = function connectComponent() {
    return connectSetup(this.context.setup)(this.getComponent());
  };

  _proto2.render = function render() {
    var Cmp = this.component;

    var _this$props = this.props,
        children = _this$props.children,
        props = _objectWithoutPropertiesLoose(_this$props, ["children"]);

    return React.createElement(Cmp, props, children);
  };

  return ContextChild;
}(React.Component);

_defineProperty(ContextChild, "contextTypes", {
  setup: PropTypes.any
});

_defineProperty(ContextChild, "propTypes", {
  children: PropTypes.node
});

_defineProperty(ContextChild, "defaultProps", {
  children: null
});

export var ContextTH =
/*#__PURE__*/
function (_ContextChild) {
  _inheritsLoose(ContextTH, _ContextChild);

  function ContextTH() {
    return _ContextChild.apply(this, arguments) || this;
  }

  var _proto3 = ContextTH.prototype;

  _proto3.getComponent = function getComponent() {
    return TH;
  };

  return ContextTH;
}(ContextChild);
export var ContextHighlight =
/*#__PURE__*/
function (_ContextChild2) {
  _inheritsLoose(ContextHighlight, _ContextChild2);

  function ContextHighlight() {
    return _ContextChild2.apply(this, arguments) || this;
  }

  var _proto4 = ContextHighlight.prototype;

  _proto4.getComponent = function getComponent() {
    return Highlight;
  };

  return ContextHighlight;
}(ContextChild);
export var ContextPagination =
/*#__PURE__*/
function (_ContextChild3) {
  _inheritsLoose(ContextPagination, _ContextChild3);

  function ContextPagination() {
    return _ContextChild3.apply(this, arguments) || this;
  }

  var _proto5 = ContextPagination.prototype;

  _proto5.getComponent = function getComponent() {
    return Pagination;
  };

  return ContextPagination;
}(ContextChild);
export var ContextPerPageSelector =
/*#__PURE__*/
function (_ContextChild4) {
  _inheritsLoose(ContextPerPageSelector, _ContextChild4);

  function ContextPerPageSelector() {
    return _ContextChild4.apply(this, arguments) || this;
  }

  var _proto6 = ContextPerPageSelector.prototype;

  _proto6.getComponent = function getComponent() {
    return PerPageSelector;
  };

  return ContextPerPageSelector;
}(ContextChild);