'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.searchName = undefined;

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

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactIntl = require('react-intl');

var _PropTypes = require('react-router/lib/PropTypes');

var _get = require('lodash/get');

var _get2 = _interopRequireDefault(_get);

var _TitleBar = require('../sections/TitleBar');

var _TitleBar2 = _interopRequireDefault(_TitleBar);

var _CsidLink = require('../navigation/CsidLink');

var _CsidLink2 = _interopRequireDefault(_CsidLink);

var _PageSizeChooser = require('../search/PageSizeChooser');

var _PageSizeChooser2 = _interopRequireDefault(_PageSizeChooser);

var _Pager = require('../search/Pager');

var _Pager2 = _interopRequireDefault(_Pager);

var _SearchResultTableContainer = require('../../containers/search/SearchResultTableContainer');

var _SearchResultTableContainer2 = _interopRequireDefault(_SearchResultTableContainer);

var _SearchResultPage = require('../../../styles/cspace-ui/SearchResultPage.css');

var _SearchResultPage2 = _interopRequireDefault(_SearchResultPage);

var _Header = require('../../../styles/cspace-ui/Header.css');

var _Header2 = _interopRequireDefault(_Header);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var messages = (0, _reactIntl.defineMessages)({
  keywordQuery: {
    'id': 'searchResultPage.keywordQuery',
    'defaultMessage': 'containing "{keyword}"'
  },
  relatedQuery: {
    'id': 'searchResultPage.relatedQuery',
    'defaultMessage': 'related to {record}'
  }
});

var searchName = exports.searchName = 'searchResultPage';

var propTypes = {
  location: _PropTypes.locationShape,
  params: _react.PropTypes.objectOf(_react.PropTypes.string),
  preferredPageSize: _react.PropTypes.number,
  search: _react.PropTypes.func,
  setPreferredPageSize: _react.PropTypes.func
};

var contextTypes = {
  config: _react.PropTypes.object.isRequired,
  router: _PropTypes.routerShape
};

var SearchResultPage = function (_Component) {
  _inherits(SearchResultPage, _Component);

  function SearchResultPage() {
    _classCallCheck(this, SearchResultPage);

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

    _this.renderFooter = _this.renderFooter.bind(_this);
    _this.renderHeader = _this.renderHeader.bind(_this);
    _this.handlePageChange = _this.handlePageChange.bind(_this);
    _this.handlePageSizeChange = _this.handlePageSizeChange.bind(_this);
    _this.handleSortChange = _this.handleSortChange.bind(_this);
    return _this;
  }

  _createClass(SearchResultPage, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      if (!this.normalizeQuery()) {
        this.search();
      }
    }
  }, {
    key: 'componentDidUpdate',
    value: function componentDidUpdate(prevProps) {
      if (this.props.params.recordType !== prevProps.params.recordType || this.props.params.vocabulary !== prevProps.params.vocabulary || this.props.params.csid !== prevProps.params.csid || this.props.params.subresource !== prevProps.params.subresource || this.props.location.query !== prevProps.location.query) {
        if (!this.normalizeQuery()) {
          this.search();
        }
      }
    }
  }, {
    key: 'getSearchDescriptor',
    value: function getSearchDescriptor() {
      var _props = this.props,
          location = _props.location,
          params = _props.params;


      var searchQuery = Object.assign({}, location.query, {
        p: parseInt(location.query.p, 10) - 1,
        size: parseInt(location.query.size, 10)
      });

      var searchDescriptor = {
        searchQuery: searchQuery
      };

      ['recordType', 'vocabulary', 'csid', 'subresource'].forEach(function (param) {
        var value = params[param];

        if (typeof value !== 'undefined') {
          searchDescriptor[param] = value;
        }
      });

      return searchDescriptor;
    }
  }, {
    key: 'getListType',
    value: function getListType(searchDescriptor) {
      if (searchDescriptor) {
        var subresource = searchDescriptor.subresource;


        if (subresource) {
          var config = this.context.config;


          return (0, _get2.default)(config, ['subresources', subresource, 'listType']);
        }
      }

      return 'common';
    }
  }, {
    key: 'normalizeQuery',
    value: function normalizeQuery() {
      var _props2 = this.props,
          location = _props2.location,
          preferredPageSize = _props2.preferredPageSize;
      var query = location.query;
      var router = this.context.router;


      if (router) {
        var normalizedQueryParams = {};

        var pageSize = parseInt(query.size, 10);

        if (isNaN(pageSize) || pageSize < 1) {
          // FIXME: Make default page size configurable
          var defaultPageSize = 20;
          var normalizedPageSize = preferredPageSize || defaultPageSize;

          normalizedQueryParams.size = normalizedPageSize.toString();
        } else if (pageSize > 2500) {
          // Services layer max is 2500
          normalizedQueryParams.size = '2500';
        } else if (pageSize.toString() !== query.size) {
          normalizedQueryParams.size = pageSize.toString();
        }

        var pageNum = parseInt(query.p, 10);

        if (isNaN(pageNum) || pageNum < 1) {
          normalizedQueryParams.p = '1';
        } else if (pageNum.toString() !== query.p) {
          normalizedQueryParams.p = pageNum.toString();
        }

        if (Object.keys(normalizedQueryParams).length > 0) {
          var newQuery = Object.assign({}, query, normalizedQueryParams);

          router.replace({
            pathname: location.pathname,
            query: newQuery
          });

          return true;
        }
      }

      return false;
    }
  }, {
    key: 'handlePageChange',
    value: function handlePageChange(pageNum) {
      var location = this.props.location;
      var router = this.context.router;


      if (router) {
        router.push({
          pathname: location.pathname,
          query: Object.assign({}, location.query, {
            p: (pageNum + 1).toString()
          })
        });
      }
    }
  }, {
    key: 'handlePageSizeChange',
    value: function handlePageSizeChange(pageSize) {
      var _props3 = this.props,
          location = _props3.location,
          setPreferredPageSize = _props3.setPreferredPageSize;
      var router = this.context.router;


      if (setPreferredPageSize) {
        setPreferredPageSize(pageSize);
      }

      if (router) {
        router.push({
          pathname: location.pathname,
          query: Object.assign({}, location.query, {
            p: '1',
            size: pageSize.toString()
          })
        });
      }
    }
  }, {
    key: 'handleSortChange',
    value: function handleSortChange(sort) {
      var location = this.props.location;
      var router = this.context.router;


      if (router) {
        router.push({
          pathname: location.pathname,
          query: Object.assign({}, location.query, {
            sort: sort
          })
        });
      }
    }
  }, {
    key: 'search',
    value: function search() {
      var search = this.props.search;
      var config = this.context.config;


      var searchDescriptor = this.getSearchDescriptor();
      var listType = this.getListType(searchDescriptor);

      if (search) {
        search(config, searchName, searchDescriptor, listType);
      }
    }
  }, {
    key: 'renderHeader',
    value: function renderHeader(_ref) {
      var searchError = _ref.searchError,
          searchResult = _ref.searchResult;

      if (searchError) {
        // FIXME: Make a proper error page
        var errorMessage = searchError.get('code') || '';

        return _react2.default.createElement(
          'header',
          { className: _Header2.default.common },
          'Error: ',
          errorMessage
        );
      }

      var location = this.props.location;


      var message = null;
      var pageSizeChooser = null;

      var pageSizeQueryParam = parseInt(location.query.size, 10);

      pageSizeChooser = _react2.default.createElement(_PageSizeChooser2.default, {
        pageSize: pageSizeQueryParam,
        onPageSizeChange: this.handlePageSizeChange
      });

      if (searchResult) {
        var config = this.context.config;


        var searchDescriptor = this.getSearchDescriptor();
        var listType = this.getListType(searchDescriptor);
        var listTypeConfig = config.listTypes[listType];
        var listNodeName = listTypeConfig.listNodeName;


        var list = searchResult.get(listNodeName);
        var totalItems = parseInt(list.get('totalItems'), 10);

        if (isNaN(totalItems)) {
          message = _react2.default.createElement(_reactIntl.FormattedMessage, listTypeConfig.messages.searching);
        } else {
          var pageNum = parseInt(list.get('pageNum'), 10);
          var pageSize = parseInt(list.get('pageSize'), 10);

          var startNum = pageNum * pageSize + 1;
          var endNum = Math.min(pageNum * pageSize + pageSize, totalItems);

          message = _react2.default.createElement(_reactIntl.FormattedMessage, _extends({}, listTypeConfig.messages.resultCount, {
            values: {
              totalItems: totalItems,
              startNum: startNum,
              endNum: endNum
            }
          }));
        }
      }

      return _react2.default.createElement(
        'header',
        { className: _Header2.default.common },
        message,
        pageSizeChooser
      );
    }
  }, {
    key: 'renderFooter',
    value: function renderFooter(_ref2) {
      var searchResult = _ref2.searchResult;

      if (searchResult) {
        var config = this.context.config;


        var searchDescriptor = this.getSearchDescriptor();
        var listType = this.getListType(searchDescriptor);
        var listTypeConfig = config.listTypes[listType];
        var listNodeName = listTypeConfig.listNodeName;


        var list = searchResult.get(listNodeName);

        var totalItems = parseInt(list.get('totalItems'), 10);
        var pageNum = parseInt(list.get('pageNum'), 10);
        var pageSize = parseInt(list.get('pageSize'), 10);
        var lastPage = Math.max(0, isNaN(totalItems) ? 0 : Math.ceil(totalItems / pageSize) - 1);

        return _react2.default.createElement(
          'footer',
          null,
          _react2.default.createElement(_Pager2.default, {
            currentPage: pageNum,
            lastPage: lastPage,
            pageSize: pageSize,
            onPageChange: this.handlePageChange,
            onPageSizeChange: this.handlePageSizeChange
          })
        );
      }

      return null;
    }
  }, {
    key: 'render',
    value: function render() {
      var config = this.context.config;


      var searchDescriptor = this.getSearchDescriptor();
      var listType = this.getListType(searchDescriptor);

      var recordType = searchDescriptor.recordType,
          vocabulary = searchDescriptor.vocabulary,
          csid = searchDescriptor.csid,
          subresource = searchDescriptor.subresource;


      var recordTypeConfig = config.recordTypes[recordType];

      if (!recordTypeConfig) {
        // FIXME: Make a proper error page
        return _react2.default.createElement(
          'div',
          { className: _SearchResultPage2.default.common },
          _react2.default.createElement(_TitleBar2.default, { title: 'Error: Unknown record type' })
        );
      }

      var vocabularyConfig = void 0;

      if (vocabulary) {
        vocabularyConfig = recordTypeConfig.vocabularies[vocabulary];

        if (!vocabularyConfig) {
          // FIXME: Make a proper error page
          return _react2.default.createElement(
            'div',
            { className: _SearchResultPage2.default.common },
            _react2.default.createElement(_TitleBar2.default, { title: 'Error: Unknown vocabulary' })
          );
        }
      }

      var subresourceConfig = void 0;

      if (subresource) {
        subresourceConfig = config.subresources[subresource];

        if (!subresourceConfig) {
          // FIXME: Make a proper error page
          return _react2.default.createElement(
            'div',
            { className: _SearchResultPage2.default.common },
            _react2.default.createElement(_TitleBar2.default, { title: 'Error: Unknown subresource' })
          );
        }
      }

      var _searchDescriptor$sea = searchDescriptor.searchQuery,
          kw = _searchDescriptor$sea.kw,
          rel = _searchDescriptor$sea.rel;


      var keywordQueryTitle = kw ? _react2.default.createElement(_reactIntl.FormattedMessage, _extends({}, messages.keywordQuery, { values: { keyword: kw } })) : null;

      var relatedQueryTitle = null;

      if (rel) {
        var recordLink = _react2.default.createElement(_CsidLink2.default, { config: config, searchName: searchName + '.rel', csid: rel });

        relatedQueryTitle = _react2.default.createElement(_reactIntl.FormattedMessage, _extends({}, messages.relatedQuery, {
          values: { record: recordLink }
        }));
      }

      var collectionName = void 0;

      if (subresourceConfig) {
        var _recordLink = _react2.default.createElement(_CsidLink2.default, { config: config, searchName: searchName + '.csid', csid: csid });

        collectionName = _react2.default.createElement(_reactIntl.FormattedMessage, _extends({}, subresourceConfig.messages.collectionName, {
          values: { record: _recordLink }
        }));
      } else if (vocabularyConfig) {
        collectionName = _react2.default.createElement(_reactIntl.FormattedMessage, vocabularyConfig.messages.collectionName);
      } else {
        collectionName = _react2.default.createElement(_reactIntl.FormattedMessage, recordTypeConfig.messages.record.collectionName);
      }

      var title = _react2.default.createElement(
        'span',
        null,
        collectionName,
        ' ',
        keywordQueryTitle,
        ' ',
        relatedQueryTitle
      );

      return _react2.default.createElement(
        'div',
        { className: _SearchResultPage2.default.common },
        _react2.default.createElement(_TitleBar2.default, { title: title }),
        _react2.default.createElement(_SearchResultTableContainer2.default, {
          config: config,
          listType: listType,
          searchName: searchName,
          searchDescriptor: searchDescriptor,
          recordType: recordType,
          renderHeader: this.renderHeader,
          renderFooter: this.renderFooter,
          onSortChange: this.handleSortChange
        })
      );
    }
  }]);

  return SearchResultPage;
}(_react.Component);

exports.default = SearchResultPage;


SearchResultPage.propTypes = propTypes;
SearchResultPage.contextTypes = contextTypes;