"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

exports.__esModule = true;
exports.default = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));

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

var _propTypes = _interopRequireDefault(require("prop-types"));

var _pick = _interopRequireDefault(require("lodash/pick"));

var _Input = _interopRequireDefault(require("../Input"));

var _utils = require("../utils");

var _utils2 = require("../Animation/utils");

var _Picker = require("../Picker");

var _utils3 = require("./utils");

var defaultProps = {
  as: 'div',
  classPrefix: 'auto-complete',
  defaultValue: '',
  placement: 'bottomStart',
  selectOnEnter: true
};

var AutoComplete = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
  var Component = props.as,
      disabled = props.disabled,
      className = props.className,
      placement = props.placement,
      selectOnEnter = props.selectOnEnter,
      classPrefix = props.classPrefix,
      defaultValue = props.defaultValue,
      data = props.data,
      valueProp = props.value,
      open = props.open,
      style = props.style,
      menuClassName = props.menuClassName,
      id = props.id,
      renderMenu = props.renderMenu,
      renderMenuItem = props.renderMenuItem,
      onSelect = props.onSelect,
      filterBy = props.filterBy,
      onKeyDown = props.onKeyDown,
      onChange = props.onChange,
      onClose = props.onClose,
      onOpen = props.onOpen,
      onFocus = props.onFocus,
      onBlur = props.onBlur,
      onMenuFocus = props.onMenuFocus,
      rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["as", "disabled", "className", "placement", "selectOnEnter", "classPrefix", "defaultValue", "data", "value", "open", "style", "menuClassName", "id", "renderMenu", "renderMenuItem", "onSelect", "filterBy", "onKeyDown", "onChange", "onClose", "onOpen", "onFocus", "onBlur", "onMenuFocus"]);
  var datalist = (0, _utils3.transformData)(data);

  var _useControlled = (0, _utils.useControlled)(valueProp, defaultValue),
      value = _useControlled[0],
      setValue = _useControlled[1];

  var _useState = (0, _react.useState)(false),
      focus = _useState[0],
      setFocus = _useState[1];

  var items = (datalist === null || datalist === void 0 ? void 0 : datalist.filter((0, _utils3.shouldDisplay)(filterBy, value))) || [];
  var hasItems = items.length > 0;
  var overlayRef = (0, _react.useRef)(null); // Used to hover the focuse item  when trigger `onKeydown`

  var _useFocusItemValue = (0, _Picker.useFocusItemValue)(value, {
    data: datalist,
    callback: onMenuFocus,
    target: function target() {
      return overlayRef.current;
    }
  }),
      focusItemValue = _useFocusItemValue.focusItemValue,
      setFocusItemValue = _useFocusItemValue.setFocusItemValue,
      handleKeyDown = _useFocusItemValue.onKeyDown;

  var handleKeyDownEvent = function handleKeyDownEvent(event) {
    if (!overlayRef.current) {
      return;
    }

    (0, _Picker.onMenuKeyDown)(event, {
      enter: selectOnEnter ? selectFocusMenuItem : undefined,
      esc: handleClose
    });
    handleKeyDown(event);
    onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
  };

  var selectFocusMenuItem = function selectFocusMenuItem(event) {
    if (!focusItemValue) {
      return;
    }

    var focusItem = datalist.find(function (item) {
      return (item === null || item === void 0 ? void 0 : item.value) === focusItemValue;
    });
    setValue(focusItemValue);
    setFocusItemValue(focusItemValue);
    handleSelect(focusItem, event);

    if (value !== focusItemValue) {
      handleChangeValue(focusItemValue, event);
    }

    handleClose();
  };

  var handleSelect = (0, _react.useCallback)(function (item, event) {
    onSelect === null || onSelect === void 0 ? void 0 : onSelect(item.value, item, event);
  }, [onSelect]);
  var handleChangeValue = (0, _react.useCallback)(function (value, event) {
    onChange === null || onChange === void 0 ? void 0 : onChange(value, event);
  }, [onChange]);

  var handleChange = function handleChange(value, event) {
    setFocusItemValue('');
    setValue(value);
    setFocus(true);
    handleChangeValue(value, event);
  };

  var handleClose = (0, _react.useCallback)(function () {
    setFocus(false);
    onClose === null || onClose === void 0 ? void 0 : onClose();
  }, [onClose]);
  var handleOpen = (0, _react.useCallback)(function () {
    setFocus(true);
    onOpen === null || onOpen === void 0 ? void 0 : onOpen();
  }, [onOpen]);
  var handleItemSelect = (0, _react.useCallback)(function (nextItemValue, item, event) {
    setValue(nextItemValue);
    setFocusItemValue(nextItemValue);
    handleSelect(item, event);

    if (value !== nextItemValue) {
      handleChangeValue(nextItemValue, event);
    }

    handleClose();
  }, [value, setValue, handleSelect, handleChangeValue, handleClose, setFocusItemValue]);
  var handleInputFocus = (0, _react.useCallback)(function (event) {
    onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
    handleOpen();
  }, [onFocus, handleOpen]);
  var handleInputBlur = (0, _react.useCallback)(function (event) {
    setTimeout(handleClose, 300);
    onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
  }, [onBlur, handleClose]);

  var _useClassNames = (0, _utils.useClassNames)(classPrefix),
      withClassPrefix = _useClassNames.withClassPrefix,
      merge = _useClassNames.merge;

  var classes = merge(className, withClassPrefix({
    disabled: disabled
  }));
  var triggerRef = (0, _react.useRef)();
  (0, _Picker.usePublicMethods)(ref, {
    triggerRef: triggerRef,
    overlayRef: overlayRef
  });

  var renderDropdownMenu = function renderDropdownMenu(positionProps, speakerRef) {
    var left = positionProps.left,
        top = positionProps.top,
        className = positionProps.className;
    var styles = {
      left: left,
      top: top
    };

    var menu = /*#__PURE__*/_react.default.createElement(_Picker.DropdownMenu, {
      id: id ? id + "-listbox" : undefined,
      classPrefix: "auto-complete-menu",
      dropdownMenuItemClassPrefix: "auto-complete-item",
      dropdownMenuItemAs: _Picker.DropdownMenuItem,
      focusItemValue: focusItemValue,
      onSelect: handleItemSelect,
      renderMenuItem: renderMenuItem,
      data: items,
      className: menuClassName
    });

    return /*#__PURE__*/_react.default.createElement(_Picker.PickerOverlay, {
      ref: (0, _utils.mergeRefs)(overlayRef, speakerRef),
      style: styles,
      className: className,
      onKeyDown: handleKeyDownEvent,
      target: triggerRef
    }, renderMenu ? renderMenu(menu) : menu);
  };

  return /*#__PURE__*/_react.default.createElement(_Picker.PickerToggleTrigger, {
    ref: triggerRef,
    placement: placement,
    pickerProps: (0, _pick.default)(props, _Picker.pickTriggerPropKeys),
    trigger: ['click', 'focus'],
    open: open || focus && hasItems,
    speaker: renderDropdownMenu
  }, /*#__PURE__*/_react.default.createElement(Component, {
    className: classes,
    style: style
  }, /*#__PURE__*/_react.default.createElement(_Input.default, (0, _extends2.default)({}, rest, {
    id: id,
    disabled: disabled,
    value: value,
    onBlur: handleInputBlur,
    onFocus: handleInputFocus,
    onChange: handleChange,
    onKeyDown: handleKeyDownEvent
  }))));
});

AutoComplete.displayName = 'AutoComplete';
AutoComplete.defaultProps = defaultProps;
AutoComplete.propTypes = (0, _extends2.default)({}, _utils2.animationPropTypes, {
  data: _propTypes.default.array,
  disabled: _propTypes.default.bool,
  onSelect: _propTypes.default.func,
  onChange: _propTypes.default.func,
  classPrefix: _propTypes.default.string,
  value: _propTypes.default.string,
  defaultValue: _propTypes.default.string,
  className: _propTypes.default.string,
  menuClassName: _propTypes.default.string,
  placement: _propTypes.default.oneOf(_utils.PLACEMENT),
  onFocus: _propTypes.default.func,
  onMenuFocus: _propTypes.default.func,
  onBlur: _propTypes.default.func,
  onKeyDown: _propTypes.default.func,
  onOpen: _propTypes.default.func,
  onClose: _propTypes.default.func,
  renderMenu: _propTypes.default.func,
  renderMenuItem: _propTypes.default.func,
  style: _propTypes.default.object,
  open: _propTypes.default.bool,
  selectOnEnter: _propTypes.default.bool,
  filterBy: _propTypes.default.func
});
var _default = AutoComplete;
exports.default = _default;