import _extends from "@babel/runtime/helpers/extends";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
var _excluded = ["className", "options", "renderOption", "id", "onChange", "onSelect", "loading", "helperText", "label", "minLetters", "notMatchText"];

var _templateObject;

import React, { useState } from "react";
import ClickAwayListener from "../../ClickAwayListener";
import createComponent from "../../system/createComponent";
import Textfield from "../TextField";
import InputAdornment from "../InputAdornment";
import useId from "../../hooks/useId";
import LoadingIcon from "../../Loading";
import Box from "../../Box";
import styled from "../../styles/styled";
import Typography from "../../Typography";
import Listbox, { ListItem } from "./Listbox";
var KEY_CODE = {
  up: 38,
  scape: 27,
  down: 40,
  enter: 13,
  tab: 9
};
var Loading = styled(LoadingIcon)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n  margin: 0 !important; //override makeStyles margin\n"])));
var Autocomplete = /*#__PURE__*/React.forwardRef(function (props, ref) {
  var className = props.className,
      options = props.options,
      renderOption = props.renderOption,
      id = props.id,
      onChange = props.onChange,
      onSelect = props.onSelect,
      _props$loading = props.loading,
      loading = _props$loading === void 0 ? false : _props$loading,
      helperText = props.helperText,
      label = props.label,
      _props$minLetters = props.minLetters,
      minLetters = _props$minLetters === void 0 ? 3 : _props$minLetters,
      _props$notMatchText = props.notMatchText,
      notMatchText = _props$notMatchText === void 0 ? "No matches found" : _props$notMatchText,
      htmlProps = _objectWithoutProperties(props, _excluded);

  var _useState = useState(""),
      _useState2 = _slicedToArray(_useState, 2),
      inputValue = _useState2[0],
      setInputValue = _useState2[1];

  var _useState3 = useState(-1),
      _useState4 = _slicedToArray(_useState3, 2),
      itemSelected = _useState4[0],
      setItemSelected = _useState4[1];

  var _useState5 = useState(false),
      _useState6 = _slicedToArray(_useState5, 2),
      isOpen = _useState6[0],
      setIsOpen = _useState6[1];

  var inputId = useId(id, "autocomplete-input");
  var listboxId = useId(undefined, "autocomplete-listbox");

  var hideOptions = function hideOptions() {
    setIsOpen(false);
    setItemSelected(-1);
  };

  var selectOption = function selectOption(option) {
    onSelect(option);
    hideOptions();
    setInputValue("");
  };

  var handleInputFocus = function handleInputFocus() {
    if (inputValue.length >= minLetters) {
      setIsOpen(true);
    }
  };

  var handleInputChange = function handleInputChange(ev) {
    var value = ev.target.value;
    if (onChange) onChange(value);
    setInputValue(value);

    if (value.length >= minLetters) {
      setIsOpen(true);
    } else {
      hideOptions();
    }
  };

  var handleInputKey = function handleInputKey(ev) {
    var keyCode = ev.keyCode;

    switch (keyCode) {
      case KEY_CODE.tab:
        hideOptions();
        break;

      case KEY_CODE.enter:
        ev.preventDefault();

        if (isOpen) {
          var selected = options[itemSelected];

          if (selected) {
            selectOption(selected);
          }
        }

        break;

      case KEY_CODE.scape:
        ev.preventDefault();
        setIsOpen(false);
        break;

      case KEY_CODE.down:
        ev.preventDefault();
        setIsOpen(true);
        setItemSelected(itemSelected === options.length - 1 ? 0 : itemSelected + 1);
        break;

      case KEY_CODE.up:
        ev.preventDefault();
        setItemSelected(itemSelected - 1 >= 0 ? itemSelected - 1 : options.length - 1);
        break;

      case KEY_CODE.RETURN:
      default:
        break;
    }
  };

  var showOptions = isOpen && !loading;
  return /*#__PURE__*/React.createElement(ClickAwayListener, {
    onClickAway: hideOptions
  }, /*#__PURE__*/React.createElement(Box, {
    position: "relative",
    className: className
  }, /*#__PURE__*/React.createElement(Textfield, _extends({
    ref: ref,
    type: "text",
    id: inputId,
    role: "combobox",
    "aria-haspopup": "listbox",
    "aria-expanded": isOpen,
    "aria-autocomplete": "list",
    "aria-controls": listboxId,
    "aria-activedescendant": isOpen ? "".concat(listboxId, "-").concat(itemSelected) : null,
    autoComplete: "off",
    value: inputValue,
    onChange: handleInputChange,
    onKeyDown: handleInputKey,
    onFocus: handleInputFocus,
    helperText: helperText,
    label: label,
    endAdornment: loading && /*#__PURE__*/React.createElement(InputAdornment, {
      position: "end"
    }, /*#__PURE__*/React.createElement(Loading, {
      size: 16
    }))
  }, htmlProps)), showOptions && /*#__PURE__*/React.createElement(Listbox, {
    id: listboxId,
    "aria-labelledby": inputId
  }, options.length === 0 && /*#__PURE__*/React.createElement(Typography, {
    variant: "small",
    align: "center",
    shade: 700
  }, notMatchText), options.length > 0 && options.map(function (option, index) {
    return /*#__PURE__*/React.createElement(ListItem, {
      key: "list-item-".concat(index),
      id: "".concat(listboxId, "-").concat(index),
      selected: index === itemSelected,
      onClick: function onClick() {
        return selectOption(option);
      }
    }, renderOption ? renderOption(option) : option);
  }))));
});
export default createComponent(Autocomplete);