'use strict';

exports.__esModule = true;

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 _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _class, _temp, _initialiseProps;

var _lite = require('algoliasearch/lite');

var _lite2 = _interopRequireDefault(_lite);

var _find = require('lodash/find');

var _find2 = _interopRequireDefault(_find);

var _pick = require('lodash/pick');

var _pick2 = _interopRequireDefault(_pick);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactInstantsearchDom = require('react-instantsearch-dom');

var _RefinementList = require('./components/RefinementList');

var _RefinementList2 = _interopRequireDefault(_RefinementList);

var _SearchBox = require('./components/SearchBox');

var _SearchBox2 = _interopRequireDefault(_SearchBox);

var _SearchResults = require('./components/SearchResults');

var _SearchResults2 = _interopRequireDefault(_SearchResults);

var _SearchTabs = require('./components/SearchTabs');

var _SearchTabs2 = _interopRequireDefault(_SearchTabs);

var _styleModule = require('./style.module.scss');

var _styleModule2 = _interopRequireDefault(_styleModule);

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 AlgoliaSearch = (_temp = _class = function (_React$Component) {
  _inherits(AlgoliaSearch, _React$Component);

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

    var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));

    _initialiseProps.call(_this);

    var enabledModules = _this.enableModuleMap(props.projectsMeta);
    _this.state = {
      activeTab: 'All',
      filters: '',
      refinementListOpen: true,
      tabs: {
        All: { filters: '' },
        Guides: { filters: 'indexName:Page AND isReference:false' },
        Reference: { filters: 'indexName:Page AND isReference:true' },
        Changelog: { filters: 'indexName:Blog' },
        Discussions: { filters: 'indexName:Discuss' },
        Pages: { filters: 'indexName:CustomPage' }
      },
      tabFilters: _this.setTabFilters([], enabledModules, true),
      enabledModules: enabledModules,
      initializeAlgolia: 'PROXY'
    };
    _this.handleTabChange = _this.handleTabChange.bind(_this);
    _this.handleFocusIn = _this.handleFocusIn.bind(_this);
    _this.rootNode = _react2.default.createRef();

    if ('matchMedia' in window) {
      _this.MQ = window.matchMedia('(max-width: 700px)');
      _this.MQ.addListener(function () {
        return _this.setState({ refinementListOpen: !_this.MQ.matches });
      });
    }
    return _this;
  }

  /* istanbul ignore next */
  // eslint-disable-next-line class-methods-use-this


  AlgoliaSearch.prototype.handleKeyboard = function handleKeyboard(e) {
    // keyboard event handling should fail silently
    try {
      var key = e.key;


      var search = document.querySelector('.' + _styleModule2.default.AlgoliaSearch);
      var searchBox = search.querySelector('input[type=search]');
      var searchHits = search.querySelector('.SearchResults-list');
      var searchPage = search.querySelector('footer');
      var focused = document.activeElement;

      if (searchBox === focused) {
        if (key === 'Tab' && e.shiftKey) {
          searchBox.select();
          e.preventDefault();
        } else if (key === 'Tab' || key === 'ArrowDown' || key === 'Enter' || key === 'ArrowUp') {
          var firstlastChild = key === 'ArrowUp' ? 'lastElementChild' : 'firstElementChild';
          searchHits[firstlastChild].focus();
          e.preventDefault();
        }
      } else if (!(searchPage && searchPage.matches(':focus-within')) && key === 'Tab' && e.shiftKey) {
        searchBox.focus();
        e.preventDefault();
      } else if (searchHits && !searchHits.matches(':focus-within') && (key === 'ArrowDown' || key === 'ArrowUp')) {
        searchHits[key === 'ArrowUp' ? 'lastElementChild' : 'firstElementChild'].focus();
        e.stopPropagation();
        e.preventDefault();
      }
    } catch (error) {
      // eslint-disable-next-line no-console
      console.warn(error);
    }
  };

  AlgoliaSearch.prototype.handleTabChange = function handleTabChange(tab) {
    /* handle keyboard events
     */
    if ((typeof tab === 'undefined' ? 'undefined' : _typeof(tab)) === 'object') {
      this.handleKeyboard(tab);
      return;
    }

    /* handle click events
     */
    if (tab in this.state.tabs) {
      this.setState(_extends({
        activeTab: tab
      }, this.state.tabs[tab]));
    }
  };

  AlgoliaSearch.prototype.handleFocusIn = function handleFocusIn() {
    if (this.state.initializeAlgolia === 'PROXY') this.setState({ initializeAlgolia: 'LIVE' });
  };

  AlgoliaSearch.prototype.render = function render() {
    var _state = this.state,
        activeTab = _state.activeTab,
        filters = _state.filters;
    var _props = this.props,
        appId = _props.appId,
        currentProject = _props.currentProject,
        defaultRefinement = _props.defaultRefinement,
        indexName = _props.indexName,
        searchApiKey = _props.searchApiKey,
        showRefinementList = _props.showRefinementList,
        style = _props.style,
        _props$projectsMeta = _props.projectsMeta,
        projectsMeta = _props$projectsMeta === undefined ? false : _props$projectsMeta,
        UrlManager = _props.UrlManager;

    /**
     * Wrap the Algolia client in a conditional, so we don't hit their
     * API on empty searches to limit unnecessary requests. More here:
     * https://algolia.com/doc/guides/building-search-ui/going-further/conditional-requests/react
     */

    var algoliaClient = {
      LIVE: (0, _lite2.default)(appId, searchApiKey),
      PROXY: {
        search: function search(requests) {
          return Promise.resolve({
            results: requests.map(function () {
              return {
                hits: [],
                nbHits: 0,
                nbPages: 0,
                page: 0,
                processingTimeMS: 0
              };
            })
          });
        }
      }
    };

    /* istanbul ignore next */
    var subdomains = !projectsMeta ? undefined : projectsMeta.reduce(function (all, _ref) {
      var id = _ref.id,
          subdomain = _ref.subdomain;

      all[id] = subdomain;
      return all;
    }, {});
    var tabRename = !projectsMeta ? {} : (0, _find2.default)(projectsMeta, { id: currentProject });

    return _react2.default.createElement(
      _reactInstantsearchDom.InstantSearch,
      { indexName: indexName, searchClient: algoliaClient[this.state.initializeAlgolia] },
      _react2.default.createElement(_reactInstantsearchDom.Configure, { filters: filters }),
      _react2.default.createElement(
        'div',
        {
          ref: this.rootNode,
          className: _styleModule2.default.AlgoliaSearch,
          onFocus: this.handleFocusIn,
          onKeyDown: this.handleTabChange,
          role: 'tabpanel',
          style: style,
          tabIndex: 0
        },
        _react2.default.createElement(
          'div',
          { className: _styleModule2.default['AlgoliaSearch-Col'] },
          _react2.default.createElement(_SearchBox2.default, null),
          _react2.default.createElement(_SearchTabs2.default, {
            activeTab: activeTab,
            onTabChange: this.handleTabChange,
            tabFilters: this.state.tabFilters,
            tabNames: tabRename ? tabRename.nav_names : {}
          }),
          _react2.default.createElement(_SearchResults2.default, {
            onReload: this.handleResultsReload,
            subdomains: subdomains,
            tab: 'Guides',
            UrlManager: UrlManager
          })
        ),
        showRefinementList && _react2.default.createElement(_RefinementList2.default, {
          attribute: 'subdomain',
          defaultRefinement: defaultRefinement,
          isOpen: this.state.refinementListOpen,
          onBlur: this.handleRefinementBlur,
          onRefine: this.setTabFilters,
          showMore: true
        })
      )
    );
  };

  return AlgoliaSearch;
}(_react2.default.Component), _initialiseProps = function _initialiseProps() {
  var _this2 = this;

  this.handleRefinementBlur = function (e) {
    var searchBox = document.querySelector('.' + _styleModule2.default.AlgoliaSearch + ' input[type=search]');
    searchBox.focus();
    searchBox.select();
    e.preventDefault();
    e.stopPropagation();
  };

  this.enableModuleMap = function (metadata) {
    return (metadata || []).reduce(function (obj, _ref2) {
      var name = _ref2.name,
          subdomain = _ref2.subdomain,
          modules = _ref2.modules;

      obj[name || subdomain] = modules;
      return obj;
    }, {});
  };

  this.setTabFilters = function () {
    var filters = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
    var enabledModules = arguments[1];
    var initiaLoad = arguments[2];

    var meta = enabledModules || _this2.state.enabledModules;
    var selectedModules = filters.length ? (0, _pick2.default)(meta, filters) : meta;

    var values = Object.values(selectedModules);
    var modules = Object.values(values).reduce(function (obj, child) {
      Object.keys(child).forEach(function (key) {
        if (obj[key]) obj[key] = !!(obj[key] + child[key]);else obj[key] = !!child[key];
      });

      return obj;
    }, {});

    var tabFilters = Object.entries(modules).filter(function (_ref3) {
      var v = _ref3[1];
      return v;
    }).map(function (_ref4) {
      var k = _ref4[0];
      return k;
    });

    if (!initiaLoad) _this2.setState({ tabFilters: tabFilters });
    return tabFilters;
  };

  this.handleResultsReload = function () {
    var focused = document.activeElement;
    var search = document.querySelector('.' + _styleModule2.default.AlgoliaSearch);
    var searchHits = search.querySelector('.SearchResults-list');
    var searchBox = search.querySelector('input[type=search]');
    setTimeout(function () {
      if (searchHits) {
        var elem = searchHits.firstElementChild;
        if (focused.matches('[focus-hit]')) elem = searchHits[focused.attributes['focus-hit'].value];
        if (elem && searchBox !== focused) elem.focus();
      }
    }, 100);
  };
}, _temp);


AlgoliaSearch.propTypes = process.env.NODE_ENV !== "production" ? {
  appId: _propTypes2.default.string.isRequired,
  currentProject: _propTypes2.default.string,
  defaultRefinement: _propTypes2.default.array,
  indexName: _propTypes2.default.string.isRequired,
  projectsMeta: _propTypes2.default.array,
  searchApiKey: _propTypes2.default.string.isRequired,
  showRefinementList: _propTypes2.default.any,
  style: _propTypes2.default.oneOfType([_propTypes2.default.object, _propTypes2.default.string]),
  UrlManager: _propTypes2.default.object
} : {};

AlgoliaSearch.defaultProps = {
  showRefinementList: true
};

exports.default = AlgoliaSearch;
module.exports = exports['default'];