import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
import React from 'react';
import PropTypes from 'prop-types';
import Pager from './Pager';
import Options from './Options';
import KEYCODE from './KeyCode';
import LOCALE from './locale/zh_CN';

function noop() {}

function isInteger(value) {
  return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
}

function defaultItemRender(page, type, element) {
  return element;
}

var Pagination = function (_React$Component) {
  _inherits(Pagination, _React$Component);

  function Pagination(props) {
    _classCallCheck(this, Pagination);

    var _this = _possibleConstructorReturn(this, (Pagination.__proto__ || Object.getPrototypeOf(Pagination)).call(this, props));

    _initialiseProps.call(_this);

    var hasOnChange = props.onChange !== noop;
    var hasCurrent = 'current' in props;
    if (hasCurrent && !hasOnChange) {
      console.warn('Warning: You provided a `current` prop to a Pagination component without an `onChange` handler. This will render a read-only component.'); // eslint-disable-line
    }

    var current = props.defaultCurrent;
    if ('current' in props) {
      current = props.current;
    }

    var pageSize = props.defaultPageSize;
    if ('pageSize' in props) {
      pageSize = props.pageSize;
    }

    _this.state = {
      current: current,
      currentInputValue: current,
      pageSize: pageSize
    };
    return _this;
  }

  _createClass(Pagination, [{
    key: 'componentWillReceiveProps',
    value: function componentWillReceiveProps(nextProps) {
      if ('current' in nextProps) {
        this.setState({
          current: nextProps.current,
          currentInputValue: nextProps.current
        });
      }

      if ('pageSize' in nextProps) {
        var newState = {};
        var current = this.state.current;
        var newCurrent = this.calculatePage(nextProps.pageSize);
        current = current > newCurrent ? newCurrent : current;
        if (!('current' in nextProps)) {
          newState.current = current;
          newState.currentInputValue = current;
        }
        newState.pageSize = nextProps.pageSize;
        this.setState(newState);
      }
    }
  }, {
    key: 'getJumpPrevPage',
    value: function getJumpPrevPage() {
      return Math.max(1, this.state.current - (this.props.showLessItems ? 3 : 5));
    }
  }, {
    key: 'getJumpNextPage',
    value: function getJumpNextPage() {
      return Math.min(this.calculatePage(), this.state.current + (this.props.showLessItems ? 3 : 5));
    }
  }, {
    key: 'getJumpPrevPage',
    value: function getJumpPrevPage() {
      return Math.max(1, this.state.current - (this.props.showLessItems ? 3 : 5));
    }
  }, {
    key: 'getJumpNextPage',
    value: function getJumpNextPage() {
      return Math.min(this.calculatePage(), this.state.current + (this.props.showLessItems ? 3 : 5));
    }
  }, {
    key: 'render',
    value: function render() {
      // When hideOnSinglePage is true and there is only 1 page, hide the pager
      if (this.props.hideOnSinglePage === true && this.props.total <= this.state.pageSize) {
        return null;
      }

      var props = this.props;
      var locale = props.locale;

      var prefixCls = props.prefixCls;
      var allPages = this.calculatePage();
      var pagerList = [];
      var jumpPrev = null;
      var jumpNext = null;
      var firstPager = null;
      var lastPager = null;
      var gotoButton = null;

      var goButton = props.showQuickJumper && props.showQuickJumper.goButton;
      var pageBufferSize = props.showLessItems ? 1 : 2;
      var _state = this.state,
          current = _state.current,
          pageSize = _state.pageSize;


      var prevPage = current - 1 > 0 ? current - 1 : 0;
      var nextPage = current + 1 < allPages ? current + 1 : allPages;

      if (props.simple) {
        if (goButton) {
          if (typeof goButton === 'boolean') {
            gotoButton = React.createElement(
              'li',
              {
                title: props.showTitle ? '' + locale.jump_to + this.state.current + '/' + allPages : null,
                className: prefixCls + '-simple-pager'
              },
              React.createElement(
                'button',
                {
                  type: 'button',
                  onClick: this.handleGoTO,
                  onKeyUp: this.handleGoTO
                },
                locale.jump_to_confirm
              )
            );
          } else {
            gotoButton = goButton;
          }
        }
        return React.createElement(
          'ul',
          { className: prefixCls + ' ' + prefixCls + '-simple ' + props.className, style: props.style },
          React.createElement(
            'li',
            {
              title: props.showTitle ? locale.prev_page : null,
              onClick: this.prev,
              tabIndex: '0',
              onKeyPress: this.runIfEnterPrev,
              className: (this.hasPrev() ? '' : prefixCls + '-disabled') + ' ' + prefixCls + '-prev',
              'aria-disabled': !this.hasPrev()
            },
            props.itemRender(prevPage, 'prev', React.createElement('a', { className: prefixCls + '-item-link' }))
          ),
          React.createElement(
            'li',
            {
              title: props.showTitle ? this.state.current + '/' + allPages : null,
              className: prefixCls + '-simple-pager'
            },
            React.createElement('input', {
              type: 'text',
              value: this.state.currentInputValue,
              onKeyDown: this.handleKeyDown,
              onKeyUp: this.handleKeyUp,
              onChange: this.handleKeyUp,
              size: '3'
            }),
            React.createElement(
              'span',
              { className: prefixCls + '-slash' },
              '\uFF0F'
            ),
            allPages
          ),
          React.createElement(
            'li',
            {
              title: props.showTitle ? locale.next_page : null,
              onClick: this.next,
              tabIndex: '0',
              onKeyPress: this.runIfEnterNext,
              className: (this.hasNext() ? '' : prefixCls + '-disabled') + ' ' + prefixCls + '-next',
              'aria-disabled': !this.hasNext()
            },
            props.itemRender(nextPage, 'next', React.createElement('a', { className: prefixCls + '-item-link' }))
          ),
          gotoButton
        );
      }

      if (allPages <= 5 + pageBufferSize * 2) {
        for (var i = 1; i <= allPages; i++) {
          var active = this.state.current === i;
          pagerList.push(React.createElement(Pager, {
            locale: locale,
            rootPrefixCls: prefixCls,
            onClick: this.handleChange,
            onKeyPress: this.runIfEnter,
            key: i,
            page: i,
            active: active,
            showTitle: props.showTitle,
            itemRender: props.itemRender
          }));
        }
      } else {
        var prevItemTitle = props.showLessItems ? locale.prev_3 : locale.prev_5;
        var nextItemTitle = props.showLessItems ? locale.next_3 : locale.next_5;
        jumpPrev = React.createElement(
          'li',
          {
            title: props.showTitle ? prevItemTitle : null,
            key: 'prev',
            onClick: this.jumpPrev,
            tabIndex: '0',
            onKeyPress: this.runIfEnterJumpPrev,
            className: prefixCls + '-jump-prev'
          },
          props.itemRender(this.getJumpPrevPage(), 'jump-prev', React.createElement('a', { className: prefixCls + '-item-link' }))
        );
        jumpNext = React.createElement(
          'li',
          {
            title: props.showTitle ? nextItemTitle : null,
            key: 'next',
            tabIndex: '0',
            onClick: this.jumpNext,
            onKeyPress: this.runIfEnterJumpNext,
            className: prefixCls + '-jump-next'
          },
          props.itemRender(this.getJumpNextPage(), 'jump-next', React.createElement('a', { className: prefixCls + '-item-link' }))
        );
        lastPager = React.createElement(Pager, {
          locale: props.locale,
          last: true,
          rootPrefixCls: prefixCls,
          onClick: this.handleChange,
          onKeyPress: this.runIfEnter,
          key: allPages,
          page: allPages,
          active: false,
          showTitle: props.showTitle,
          itemRender: props.itemRender
        });
        firstPager = React.createElement(Pager, {
          locale: props.locale,
          rootPrefixCls: prefixCls,
          onClick: this.handleChange,
          onKeyPress: this.runIfEnter,
          key: 1,
          page: 1,
          active: false,
          showTitle: props.showTitle,
          itemRender: props.itemRender
        });

        var left = Math.max(1, current - pageBufferSize);
        var right = Math.min(current + pageBufferSize, allPages);

        if (current - 1 <= pageBufferSize) {
          right = 1 + pageBufferSize * 2;
        }

        if (allPages - current <= pageBufferSize) {
          left = allPages - pageBufferSize * 2;
        }

        for (var _i = left; _i <= right; _i++) {
          var _active = current === _i;
          pagerList.push(React.createElement(Pager, {
            locale: props.locale,
            rootPrefixCls: prefixCls,
            onClick: this.handleChange,
            onKeyPress: this.runIfEnter,
            key: _i,
            page: _i,
            active: _active,
            showTitle: props.showTitle,
            itemRender: props.itemRender
          }));
        }

        if (current - 1 >= pageBufferSize * 2 && current !== 1 + 2) {
          pagerList[0] = React.cloneElement(pagerList[0], {
            className: prefixCls + '-item-after-jump-prev'
          });
          pagerList.unshift(jumpPrev);
        }
        if (allPages - current >= pageBufferSize * 2 && current !== allPages - 2) {
          pagerList[pagerList.length - 1] = React.cloneElement(pagerList[pagerList.length - 1], {
            className: prefixCls + '-item-before-jump-next'
          });
          pagerList.push(jumpNext);
        }

        if (left !== 1) {
          pagerList.unshift(firstPager);
        }
        if (right !== allPages) {
          pagerList.push(lastPager);
        }
      }

      var totalText = null;

      if (props.showTotal) {
        totalText = React.createElement(
          'li',
          { className: prefixCls + '-total-text' },
          props.showTotal(props.total, [(current - 1) * pageSize + 1, current * pageSize > props.total ? props.total : current * pageSize])
        );
      }
      var prevDisabled = !this.hasPrev();
      var nextDisabled = !this.hasNext();
      return React.createElement(
        'ul',
        {
          className: prefixCls + ' ' + props.className,
          style: props.style,
          unselectable: 'unselectable'
        },
        totalText,
        React.createElement(
          'li',
          {
            title: props.showTitle ? locale.prev_page : null,
            onClick: this.prev,
            tabIndex: '0',
            onKeyPress: this.runIfEnterPrev,
            className: (!prevDisabled ? '' : prefixCls + '-disabled') + ' ' + prefixCls + '-prev',
            'aria-disabled': prevDisabled
          },
          props.itemRender(prevPage, 'prev', React.createElement('a', { className: prefixCls + '-item-link' }))
        ),
        pagerList,
        React.createElement(
          'li',
          {
            title: props.showTitle ? locale.next_page : null,
            onClick: this.next,
            tabIndex: '0',
            onKeyPress: this.runIfEnterNext,
            className: (!nextDisabled ? '' : prefixCls + '-disabled') + ' ' + prefixCls + '-next',
            'aria-disabled': nextDisabled
          },
          props.itemRender(nextPage, 'next', React.createElement('a', { className: prefixCls + '-item-link' }))
        ),
        React.createElement(Options, {
          locale: props.locale,
          rootPrefixCls: prefixCls,
          selectComponentClass: props.selectComponentClass,
          selectPrefixCls: props.selectPrefixCls,
          changeSize: this.props.showSizeChanger ? this.changePageSize : null,
          current: this.state.current,
          pageSize: this.state.pageSize,
          pageSizeOptions: this.props.pageSizeOptions,
          quickGo: this.props.showQuickJumper ? this.handleChange : null,
          goButton: goButton
        })
      );
    }
  }]);

  return Pagination;
}(React.Component);

Pagination.propTypes = {
  current: PropTypes.number,
  defaultCurrent: PropTypes.number,
  total: PropTypes.number,
  pageSize: PropTypes.number,
  defaultPageSize: PropTypes.number,
  onChange: PropTypes.func,
  hideOnSinglePage: PropTypes.bool,
  showSizeChanger: PropTypes.bool,
  showLessItems: PropTypes.bool,
  onShowSizeChange: PropTypes.func,
  selectComponentClass: PropTypes.func,
  showQuickJumper: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
  showTitle: PropTypes.bool,
  pageSizeOptions: PropTypes.arrayOf(PropTypes.string),
  showTotal: PropTypes.func,
  locale: PropTypes.object,
  style: PropTypes.object,
  itemRender: PropTypes.func
};
Pagination.defaultProps = {
  defaultCurrent: 1,
  total: 0,
  defaultPageSize: 10,
  onChange: noop,
  className: '',
  selectPrefixCls: 'rc-select',
  prefixCls: 'rc-pagination',
  selectComponentClass: null,
  hideOnSinglePage: false,
  showQuickJumper: false,
  showSizeChanger: false,
  showLessItems: false,
  showTitle: true,
  onShowSizeChange: noop,
  locale: LOCALE,
  style: {},
  itemRender: defaultItemRender
};

var _initialiseProps = function _initialiseProps() {
  var _this2 = this;

  this.calculatePage = function (p) {
    var pageSize = p;
    if (typeof pageSize === 'undefined') {
      pageSize = _this2.state.pageSize;
    }
    return Math.floor((_this2.props.total - 1) / pageSize) + 1;
  };

  this.isValid = function (page) {
    return isInteger(page) && page >= 1 && page !== _this2.state.current;
  };

  this.handleKeyDown = function (e) {
    if (e.keyCode === KEYCODE.ARROW_UP || e.keyCode === KEYCODE.ARROW_DOWN) {
      e.preventDefault();
    }
  };

  this.handleKeyUp = function (e) {
    var inputValue = e.target.value;
    var currentInputValue = _this2.state.currentInputValue;
    var value = void 0;

    if (inputValue === '') {
      value = inputValue;
    } else if (isNaN(Number(inputValue))) {
      value = currentInputValue;
    } else {
      value = Number(inputValue);
    }

    if (value !== currentInputValue) {
      _this2.setState({
        currentInputValue: value
      });
    }

    if (e.keyCode === KEYCODE.ENTER) {
      _this2.handleChange(value);
    } else if (e.keyCode === KEYCODE.ARROW_UP) {
      _this2.handleChange(value - 1);
    } else if (e.keyCode === KEYCODE.ARROW_DOWN) {
      _this2.handleChange(value + 1);
    }
  };

  this.changePageSize = function (size) {
    var current = _this2.state.current;
    var newCurrent = _this2.calculatePage(size);
    current = current > newCurrent ? newCurrent : current;
    if (typeof size === 'number') {
      if (!('pageSize' in _this2.props)) {
        _this2.setState({
          pageSize: size
        });
      }
      if (!('current' in _this2.props)) {
        _this2.setState({
          current: current,
          currentInputValue: current
        });
      }
    }
    _this2.props.onShowSizeChange(current, size);
  };

  this.handleChange = function (p) {
    var page = p;
    if (_this2.isValid(page)) {
      if (page > _this2.calculatePage()) {
        page = _this2.calculatePage();
      }

      if (!('current' in _this2.props)) {
        _this2.setState({
          current: page,
          currentInputValue: page
        });
      }

      var pageSize = _this2.state.pageSize;
      _this2.props.onChange(page, pageSize);

      return page;
    }

    return _this2.state.current;
  };

  this.prev = function () {
    if (_this2.hasPrev()) {
      _this2.handleChange(_this2.state.current - 1);
    }
  };

  this.next = function () {
    if (_this2.hasNext()) {
      _this2.handleChange(_this2.state.current + 1);
    }
  };

  this.jumpPrev = function () {
    _this2.handleChange(_this2.getJumpPrevPage());
  };

  this.jumpNext = function () {
    _this2.handleChange(_this2.getJumpNextPage());
  };

  this.hasPrev = function () {
    return _this2.state.current > 1;
  };

  this.hasNext = function () {
    return _this2.state.current < _this2.calculatePage();
  };

  this.runIfEnter = function (event, callback) {
    for (var _len = arguments.length, restParams = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
      restParams[_key - 2] = arguments[_key];
    }

    if (event.key === 'Enter' || event.charCode === 13) {
      callback.apply(undefined, restParams);
    }
  };

  this.runIfEnterPrev = function (e) {
    _this2.runIfEnter(e, _this2.prev);
  };

  this.runIfEnterNext = function (e) {
    _this2.runIfEnter(e, _this2.next);
  };

  this.runIfEnterJumpPrev = function (e) {
    _this2.runIfEnter(e, _this2.jumpPrev);
  };

  this.runIfEnterJumpNext = function (e) {
    _this2.runIfEnter(e, _this2.jumpNext);
  };

  this.handleGoTO = function (e) {
    if (e.keyCode === KEYCODE.ENTER || e.type === 'click') {
      _this2.handleChange(_this2.state.currentInputValue);
    }
  };
};

export default Pagination;