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() {}

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

    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,
      _current: current,
      pageSize: pageSize
    };

    ['render', '_handleChange', '_handleKeyUp', '_handleKeyDown', '_changePageSize', '_isValid', '_prev', '_next', '_hasPrev', '_hasNext', '_jumpPrev', '_jumpNext'].forEach(function (method) {
      return _this[method] = _this[method].bind(_this);
    });
    return _this;
  }

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

      if ('pageSize' in nextProps) {
        var newState = {};
        var current = this.state.current;
        var newCurrent = this._calcPage(nextProps.pageSize);
        current = current > newCurrent ? newCurrent : current;
        if (!('current' in nextProps)) {
          newState.current = current;
          newState._current = current;
        }
        newState.pageSize = nextProps.pageSize;
        this.setState(newState);
      }
    }

    // private methods

  }, {
    key: '_calcPage',
    value: function _calcPage(p) {
      var pageSize = p;
      if (typeof pageSize === 'undefined') {
        pageSize = this.state.pageSize;
      }
      return Math.floor((this.props.total - 1) / pageSize) + 1;
    }
  }, {
    key: '_isValid',
    value: function _isValid(page) {
      return typeof page === 'number' && page >= 1 && page !== this.state.current;
    }
  }, {
    key: '_handleKeyDown',
    value: function _handleKeyDown(evt) {
      if (evt.keyCode === KEYCODE.ARROW_UP || evt.keyCode === KEYCODE.ARROW_DOWN) {
        evt.preventDefault();
      }
    }
  }, {
    key: '_handleKeyUp',
    value: function _handleKeyUp(evt) {
      var _val = evt.target.value;
      var val = void 0;

      if (_val === '') {
        val = _val;
      } else if (isNaN(Number(_val))) {
        val = this.state._current;
      } else {
        val = Number(_val);
      }

      this.setState({
        _current: val
      });

      if (evt.keyCode === KEYCODE.ENTER) {
        this._handleChange(val);
      } else if (evt.keyCode === KEYCODE.ARROW_UP) {
        this._handleChange(val - 1);
      } else if (evt.keyCode === KEYCODE.ARROW_DOWN) {
        this._handleChange(val + 1);
      }
    }
  }, {
    key: '_changePageSize',
    value: function _changePageSize(size) {
      var current = this.state.current;
      var newCurrent = this._calcPage(size);
      current = current > newCurrent ? newCurrent : current;
      if (typeof size === 'number') {
        if (!('pageSize' in this.props)) {
          this.setState({
            pageSize: size
          });
        }
        if (!('current' in this.props)) {
          this.setState({
            current: current,
            _current: current
          });
        }
      }
      this.props.onShowSizeChange(current, size);
    }
  }, {
    key: '_handleChange',
    value: function _handleChange(p) {
      var page = p;
      if (this._isValid(page)) {
        if (page > this._calcPage()) {
          page = this._calcPage();
        }

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

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

        return page;
      }

      return this.state.current;
    }
  }, {
    key: '_prev',
    value: function _prev() {
      if (this._hasPrev()) {
        this._handleChange(this.state.current - 1);
      }
    }
  }, {
    key: '_next',
    value: function _next() {
      if (this._hasNext()) {
        this._handleChange(this.state.current + 1);
      }
    }
  }, {
    key: '_jumpPrev',
    value: function _jumpPrev() {
      this._handleChange(Math.max(1, this.state.current - (this.props.showLessItems ? 3 : 5)));
    }
  }, {
    key: '_jumpNext',
    value: function _jumpNext() {
      this._handleChange(Math.min(this._calcPage(), this.state.current + (this.props.showLessItems ? 3 : 5)));
    }
  }, {
    key: '_hasPrev',
    value: function _hasPrev() {
      return this.state.current > 1;
    }
  }, {
    key: '_hasNext',
    value: function _hasNext() {
      return this.state.current < this._calcPage();
    }
  }, {
    key: 'render',
    value: function render() {
      var props = this.props;
      var locale = props.locale;

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

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


      if (props.simple) {
        return React.createElement(
          'ul',
          { className: prefixCls + ' ' + prefixCls + '-simple ' + props.className },
          React.createElement(
            'li',
            {
              title: props.showTitle ? locale.prev_page : null,
              onClick: this._prev,
              className: (this._hasPrev() ? '' : prefixCls + '-disabled') + ' ' + prefixCls + '-prev',
              'aria-disabled': !this._hasPrev()
            },
            React.createElement('a', null)
          ),
          React.createElement(
            'li',
            {
              title: props.showTitle ? this.state.current + '/' + allPages : null,
              className: prefixCls + '-simple-pager'
            },
            React.createElement('input', {
              type: 'text',
              value: this.state._current,
              onKeyDown: this._handleKeyDown,
              onKeyUp: this._handleKeyUp,
              onChange: this._handleKeyUp
            }),
            React.createElement(
              'span',
              { className: prefixCls + '-slash' },
              '\uFF0F'
            ),
            allPages
          ),
          React.createElement(
            'li',
            {
              title: props.showTitle ? locale.next_page : null,
              onClick: this._next,
              className: (this._hasNext() ? '' : prefixCls + '-disabled') + ' ' + prefixCls + '-next',
              'aria-disabled': !this._hasNext()
            },
            React.createElement('a', null)
          )
        );
      }

      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.bind(this, i),
            key: i,
            page: i,
            active: active,
            showTitle: props.showTitle
          }));
        }
      } 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,
            className: prefixCls + '-jump-prev'
          },
          React.createElement('a', null)
        );
        jumpNext = React.createElement(
          'li',
          {
            title: props.showTitle ? nextItemTitle : null,
            key: 'next',
            onClick: this._jumpNext,
            className: prefixCls + '-jump-next'
          },
          React.createElement('a', null)
        );
        lastPager = React.createElement(Pager, {
          locale: props.locale,
          last: true,
          rootPrefixCls: prefixCls,
          onClick: this._handleChange.bind(this, allPages),
          key: allPages,
          page: allPages,
          active: false,
          showTitle: props.showTitle
        });
        firstPager = React.createElement(Pager, {
          locale: props.locale,
          rootPrefixCls: prefixCls,
          onClick: this._handleChange.bind(this, 1),
          key: 1,
          page: 1,
          active: false,
          showTitle: props.showTitle
        });

        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.bind(this, _i),
            key: _i,
            page: _i,
            active: _active,
            showTitle: props.showTitle
          }));
        }

        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(
          'span',
          { 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,
            className: (!prevDisabled ? '' : prefixCls + '-disabled') + ' ' + prefixCls + '-prev',
            'aria-disabled': prevDisabled
          },
          React.createElement('a', null)
        ),
        pagerList,
        React.createElement(
          'li',
          {
            title: props.showTitle ? locale.next_page : null,
            onClick: this._next,
            className: (!nextDisabled ? '' : prefixCls + '-disabled') + ' ' + prefixCls + '-next',
            'aria-disabled': nextDisabled
          },
          React.createElement('a', null)
        ),
        React.createElement(Options, {
          locale: props.locale,
          rootPrefixCls: prefixCls,
          selectComponentClass: props.selectComponentClass,
          selectPrefixCls: props.selectPrefixCls,
          changeSize: this.props.showSizeChanger ? this._changePageSize.bind(this) : null,
          current: this.state.current,
          pageSize: this.state.pageSize,
          pageSizeOptions: this.props.pageSizeOptions,
          quickGo: this.props.showQuickJumper ? this._handleChange.bind(this) : null
        })
      );
    }
  }]);

  return Pagination;
}(React.Component);

Pagination.propTypes = {
  current: PropTypes.number,
  defaultCurrent: PropTypes.number,
  total: PropTypes.number,
  pageSize: PropTypes.number,
  defaultPageSize: PropTypes.number,
  onChange: PropTypes.func,
  showSizeChanger: PropTypes.bool,
  showLessItems: PropTypes.bool,
  onShowSizeChange: PropTypes.func,
  selectComponentClass: PropTypes.func,
  showQuickJumper: PropTypes.bool,
  showTitle: PropTypes.bool,
  pageSizeOptions: PropTypes.arrayOf(PropTypes.string),
  showTotal: PropTypes.func,
  locale: PropTypes.object,
  style: PropTypes.object
};

Pagination.defaultProps = {
  defaultCurrent: 1,
  total: 0,
  defaultPageSize: 10,
  onChange: noop,
  className: '',
  selectPrefixCls: 'rc-select',
  prefixCls: 'rc-pagination',
  selectComponentClass: null,
  showQuickJumper: false,
  showSizeChanger: false,
  showLessItems: false,
  showTitle: true,
  onShowSizeChange: noop,
  locale: LOCALE,
  style: {}
};

export default Pagination;