"use strict";

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.SearchInput = void 0;

var _react = _interopRequireWildcard(require("react"));

var _styledComponents = _interopRequireDefault(require("styled-components"));

var _searchInput = require("./search-input.proptypes");

var _branding = require("../../../mixins/branding");

var _primitives = require("../../../primitives");

var _searchResultsWrapper = require("./components/search-results-wrapper");

var _clickableSearchResult = require("./components/clickable-search-result");

var _searchResultSeparator = require("./components/search-result-separator");

var _searchInputField = require("../search-input-field");

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

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

var NotFoundItem = (0, _styledComponents["default"])(_clickableSearchResult.ClickableSearchResult).withConfig({
  displayName: "NotFoundItem",
  componentId: "amedir-0"
})(["color:", ";"], (0, _branding.getPaletteColor)('greyscale-dark'));

var SearchInput = function SearchInput(_ref) {
  var _ref$value = _ref.value,
      value = _ref$value === void 0 ? '' : _ref$value,
      placeholder = _ref.placeholder,
      searchResults = _ref.searchResults,
      onChange = _ref.onChange,
      _ref$handleClear = _ref.handleClear,
      handleClear = _ref$handleClear === void 0 ? function () {} : _ref$handleClear,
      _ref$onSearchResultCl = _ref.onSearchResultClicked,
      onSearchResultClicked = _ref$onSearchResultCl === void 0 ? function (_id, _value) {} : _ref$onSearchResultCl,
      _ref$large = _ref.large,
      large = _ref$large === void 0 ? true : _ref$large,
      _ref$bold = _ref.bold,
      bold = _ref$bold === void 0 ? false : _ref$bold,
      _ref$allowNotFound = _ref.allowNotFound,
      allowNotFound = _ref$allowNotFound === void 0 ? false : _ref$allowNotFound,
      notFoundText = _ref.notFoundText,
      hideLabel = _ref.hideLabel,
      label = _ref.label,
      _ref$renderItem = _ref.renderItem,
      renderItem = _ref$renderItem === void 0 ? function (_ref2) {
    var text = _ref2.text;
    return text;
  } : _ref$renderItem;

  var _useState = (0, _react.useState)(value),
      _useState2 = _slicedToArray(_useState, 2),
      searchInput = _useState2[0],
      setSearchInput = _useState2[1];

  var _useState3 = (0, _react.useState)(false),
      _useState4 = _slicedToArray(_useState3, 2),
      showSearchResults = _useState4[0],
      setShowSearchResults = _useState4[1];

  var _useState5 = (0, _react.useState)(-1),
      _useState6 = _slicedToArray(_useState5, 2),
      selectedSearchResultIndex = _useState6[0],
      setSelectedSearchResultIndex = _useState6[1];

  var _useState7 = (0, _react.useState)(),
      _useState8 = _slicedToArray(_useState7, 2),
      timeoutId = _useState8[0],
      setTimeoutId = _useState8[1];

  var handleChange = (0, _react.useCallback)(function (newSearchInput) {
    setSelectedSearchResultIndex(-1);
    setSearchInput(newSearchInput);
    onChange(newSearchInput);
    setShowSearchResults(!!newSearchInput);
  }, [onChange]);
  var onClear = (0, _react.useCallback)(function () {
    setSelectedSearchResultIndex(-1);
    setSearchInput('');
    onChange('');
    setShowSearchResults(false);
    handleClear();
  }, [handleClear, onChange]);
  var handleSearchResultClicked = (0, _react.useCallback)(function (id, newValue) {
    var _newValue;

    setSelectedSearchResultIndex(-1);
    setShowSearchResults(false);
    setSearchInput((_newValue = newValue) !== null && _newValue !== void 0 ? _newValue : '');
    onSearchResultClicked(id, newValue);
  }, [onSearchResultClicked]);
  var handleSearchInputFocused = (0, _react.useCallback)(function () {
    setShowSearchResults(!!searchInput.length);
  }, [searchInput]);
  var handleSearchInputBlurred = (0, _react.useCallback)(function () {
    // Wait before closing the drop-down so clicking on an item has time
    // to register before the list is dismissed.
    setTimeoutId(window.setTimeout(function () {
      return setShowSearchResults(false);
    }, 200));
  }, []); // Clear any outstanding timeout when the component is unmounted.

  (0, _react.useEffect)(function () {
    return function () {
      return timeoutId && window.clearTimeout(timeoutId);
    };
  });
  var handleKeyDown = (0, _react.useCallback)(function (evt) {
    var enterKey = evt.keyCode === 13;

    if (enterKey && selectedSearchResultIndex >= 0) {
      var clickedResult = searchResults[selectedSearchResultIndex];

      if (clickedResult) {
        handleSearchResultClicked(clickedResult.id, clickedResult.text);
      } else {
        handleSearchResultClicked();
      }

      evt.stopPropagation();
      evt.preventDefault();
    }
  }, [handleSearchResultClicked, searchResults, selectedSearchResultIndex]);
  var handleKeyUp = (0, _react.useCallback)(function (evt) {
    var highlightedIndex = selectedSearchResultIndex;
    var upKey = evt.keyCode === 38;
    var downKey = evt.keyCode === 40;
    var escapeKey = evt.keyCode === 27; // Search results should be 1 longer for if the last option is the "Not Found" option

    var searchResultsLength = searchResults.length - (allowNotFound ? 0 : 1);

    if (escapeKey) {
      highlightedIndex = -1;
      setShowSearchResults(false);
    } else if (upKey && selectedSearchResultIndex >= 0) {
      var selectedSearchResult;

      do {
        highlightedIndex--;
        selectedSearchResult = searchResults[highlightedIndex];
      } while (selectedSearchResult && selectedSearchResult.isSeparator);
    } else if (downKey && selectedSearchResultIndex < searchResultsLength) {
      var _selectedSearchResult;

      do {
        highlightedIndex++;
        _selectedSearchResult = searchResults[highlightedIndex];
      } while (_selectedSearchResult && _selectedSearchResult.isSeparator);
    }

    setSelectedSearchResultIndex(highlightedIndex);
  }, [allowNotFound, searchResults, selectedSearchResultIndex]);

  var handleClick = function handleClick(id, result) {
    handleSearchResultClicked(id, result);
  };
  /**
   * In the handlers, `searchResults` is outdated so we need to check it in the render.
   * Make an exception to show search results regardless if there are any for `allowNotFound`
   */


  var shouldShowSearchResults = showSearchResults && (searchResults.length || allowNotFound);
  return _react["default"].createElement(_primitives.Box, {
    stacked: "column",
    onKeyUp: handleKeyUp,
    onKeyDown: handleKeyDown,
    onFocus: handleSearchInputFocused,
    onBlur: handleSearchInputBlurred
  }, _react["default"].createElement("div", {
    style: {
      position: 'relative'
    }
  }, _react["default"].createElement(_searchInputField.SearchInputField, {
    label: label,
    onChange: handleChange,
    value: searchInput,
    bold: bold,
    placeholder: placeholder,
    large: large,
    handleClear: onClear,
    hideLabel: hideLabel
  }), _react["default"].createElement(_searchResultsWrapper.SearchResultsWrapper, {
    large: large,
    style: {
      display: shouldShowSearchResults ? 'block' : 'none'
    }
  }, searchResults.map(function (result, i) {
    return result.isSeparator ? _react["default"].createElement(_searchResultSeparator.SearchResultSeparator, {
      key: result.id,
      large: large
    }, result.text) : _react["default"].createElement(_clickableSearchResult.ClickableSearchResult, {
      key: result.id,
      onClick: function onClick() {
        return handleClick(result.id, result.text);
      },
      selected: selectedSearchResultIndex === i,
      large: large,
      bold: bold
    }, renderItem(result));
  }), allowNotFound && _react["default"].createElement(NotFoundItem, {
    onClick: function onClick() {
      return handleClick();
    },
    selected: selectedSearchResultIndex === searchResults.length,
    large: large,
    bold: false
  }, notFoundText))));
};

exports.SearchInput = SearchInput;
SearchInput.displayName = 'SearchInput';
SearchInput.propTypes = _searchInput.searchInputPropTypes;