import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
var _excluded = ["className", "valid", "invalid", "disabled", "color", "selectedOptions", "placeholder", "options", "expanded", "defaultExpanded", "withIcons", "multiSelect", "size", "onClick", "onToggle", "onOptionChange"];

var _ICON_SIZE_MAP;

import * as React from 'react';
import classnames from 'classnames';
import { FloatingFocusManager, FloatingOverlay, useMergeRefs } from '@floating-ui/react';
import { isTouchScreen, __DEV__, invariant, generateId } from '../utils';
import Icon from '../icons/Icon';
import SubjectIcon from '../subject-icons/SubjectIcon';
import Text from '../text/Text';
import useSelectMenu from './useSelectMenu';
import useFloatingSelectMenu from './useFloatingSelectMenu';
import useSelectMenuAnimations from './useSelectMenuAnimations';
import SelectMenuOption from './SelectMenuOption';
export var SIZE = {
  S: 's',
  M: 'm',
  L: 'l'
};
var DEFAULT_SIZE = SIZE.M;
var ICON_SIZE_MAP = (_ICON_SIZE_MAP = {}, _defineProperty(_ICON_SIZE_MAP, SIZE.L, 32), _defineProperty(_ICON_SIZE_MAP, SIZE.M, 24), _defineProperty(_ICON_SIZE_MAP, SIZE.S, 16), _ICON_SIZE_MAP);
export var COLOR = {
  DEFAULT: 'default',
  WHITE: 'white'
};
var SelectMenu = /*#__PURE__*/React.forwardRef(function (props, ref) {
  var _classnames, _floatingProps$y, _floatingProps$x;

  var className = props.className,
      valid = props.valid,
      invalid = props.invalid,
      disabled = props.disabled,
      color = props.color,
      _props$selectedOption = props.selectedOptions,
      selectedOptions = _props$selectedOption === void 0 ? [] : _props$selectedOption,
      _props$placeholder = props.placeholder,
      placeholder = _props$placeholder === void 0 ? 'Select...' : _props$placeholder,
      _props$options = props.options,
      options = _props$options === void 0 ? [] : _props$options,
      _props$expanded = props.expanded,
      expanded = _props$expanded === void 0 ? undefined : _props$expanded,
      _props$defaultExpande = props.defaultExpanded,
      defaultExpanded = _props$defaultExpande === void 0 ? undefined : _props$defaultExpande,
      _props$withIcons = props.withIcons,
      withIcons = _props$withIcons === void 0 ? false : _props$withIcons,
      _props$multiSelect = props.multiSelect,
      multiSelect = _props$multiSelect === void 0 ? false : _props$multiSelect,
      _props$size = props.size,
      size = _props$size === void 0 ? DEFAULT_SIZE : _props$size,
      onClick = props.onClick,
      onToggle = props.onToggle,
      onOptionChange = props.onOptionChange,
      additionalProps = _objectWithoutProperties(props, _excluded);

  var _React$useRef = React.useRef("select-".concat(generateId())),
      id = _React$useRef.current;

  if (__DEV__) {
    invariant(!(valid && invalid), "Select cannot be valid and invalid at the same time.");
  }

  var wrapperId = "".concat(id, "-wrapper");
  var popupClassName = 'sg-select-menu__popup';
  var popupContentClassName = 'sg-select-menu__options-wrapper';
  var selectElementClassName = 'sg-select-menu__element';
  var floatingContainerClassName = 'sg-select-menu__options-floating-container';

  var _useSelectMenuAnimati = useSelectMenuAnimations({
    selectId: wrapperId,
    floatingContainerClassName: floatingContainerClassName,
    popupClassName: popupClassName,
    popupContentClassName: popupContentClassName,
    selectElementClassName: selectElementClassName
  }),
      animateEntry = _useSelectMenuAnimati.animateEntry,
      animateExit = _useSelectMenuAnimati.animateExit;

  var _useSelectMenu = useSelectMenu({
    id: id,
    valid: valid,
    invalid: invalid,
    expanded: expanded,
    defaultExpanded: defaultExpanded,
    disabled: disabled,
    multiSelect: multiSelect,
    onEntry: animateEntry,
    onExit: animateExit,
    onToggle: onToggle,
    onOptionChange: onOptionChange
  }),
      isExpanded = _useSelectMenu.isExpanded,
      onOpenChange = _useSelectMenu.onOpenChange,
      handleOptionSelect = _useSelectMenu.handleOptionSelect;

  var _useFloatingSelectMen = useFloatingSelectMenu({
    isExpanded: isExpanded,
    onOpenChange: onOpenChange
  }),
      interactions = _useFloatingSelectMen.interactions,
      floatingProps = _useFloatingSelectMen.floatingProps,
      refs = _useFloatingSelectMen.refs,
      listRef = _useFloatingSelectMen.listRef,
      context = _useFloatingSelectMen.context,
      isMounted = _useFloatingSelectMen.isMounted,
      status = _useFloatingSelectMen.status,
      activeIndex = _useFloatingSelectMen.activeIndex;

  var optionsElements = options.map(function (option, index) {
    if (option.label || option.value) {
      var isSelected = selectedOptions.some(function (selectedOption) {
        return selectedOption.value === option.value;
      });
      var optionInteractions = interactions.getItemProps({
        // Handle pointer select.
        onClick: function onClick() {
          handleOptionSelect(option);
        },
        // Handle keyboard select.
        onKeyDown: function onKeyDown(event) {
          if (event.key === 'Enter') {
            event.preventDefault();
            handleOptionSelect(option);
          } // Only if not using typeahead.


          if (event.key === ' ' && !context.dataRef.current.typing) {
            event.preventDefault();
            handleOptionSelect(option);
          }
        }
      });
      return /*#__PURE__*/React.createElement(SelectMenuOption, {
        key: option.value,
        ref: function ref(node) {
          listRef.current[index] = node;
        },
        option: option,
        isSelected: isSelected,
        multiSelect: multiSelect,
        withIcon: withIcons,
        interactions: optionInteractions,
        tabIndex: index === activeIndex ? 0 : -1
      });
    }

    return null;
  });
  var selectDisplayValue = React.useMemo(function () {
    if (!selectedOptions.length) return /*#__PURE__*/React.createElement(Text, {
      className: "sg-select-menu__placeholder",
      size: "small",
      color: "text-gray-60"
    }, placeholder);

    if (selectedOptions.length === 1) {
      var _ref = selectedOptions[0] || {},
          label = _ref.label,
          icon = _ref.icon;

      var displayLabel = /*#__PURE__*/React.createElement(Text, {
        size: "small",
        className: "sg-select-menu__element-label",
        "aria-label": label
      }, label);

      if (withIcons && icon !== null && icon !== void 0 && icon.name) {
        var _ref2 = icon || {},
            name = _ref2.name,
            _ref2$isSubjectIcon = _ref2.isSubjectIcon,
            isSubjectIcon = _ref2$isSubjectIcon === void 0 ? false : _ref2$isSubjectIcon;

        var displayedIcon;

        if (isSubjectIcon) {
          var iconName = name; // Add an icon name key so only icon different
          // from the previous one will have opacity animation

          displayedIcon = /*#__PURE__*/React.createElement(SubjectIcon, {
            key: iconName,
            className: "sg-select-menu__element-label-icon",
            size: "small",
            type: iconName
          });
        } else {
          var _iconName = name; // Add an icon name key so only icon different
          // from the previous one will have opacity animation

          displayedIcon = /*#__PURE__*/React.createElement(Icon, {
            key: _iconName,
            className: "sg-select-menu__element-label-icon",
            size: 24,
            color: "icon-black",
            type: _iconName
          });
        }

        return /*#__PURE__*/React.createElement(React.Fragment, null, displayedIcon, displayLabel);
      }

      return displayLabel;
    } else {
      var _label = [];
      selectedOptions.map(function (option) {
        return _label.push(option.label);
      });

      var labelString = _label.join(', ');

      return /*#__PURE__*/React.createElement(Text, {
        size: "small",
        className: "sg-select-menu__element-label",
        "aria-label": labelString
      }, labelString);
    }
  }, [placeholder, withIcons, selectedOptions]);
  var selectClass = classnames('sg-select-menu', (_classnames = {
    'sg-select-menu--selected': selectedOptions.length,
    'sg-select-menu--valid': valid,
    'sg-select-menu--invalid': invalid,
    'sg-select-menu--disabled': disabled
  }, _defineProperty(_classnames, "sg-select-menu--".concat(String(size)), size && size !== DEFAULT_SIZE), _defineProperty(_classnames, "sg-select-menu--".concat(String(color)), color), _classnames), className);
  var selectRef = useMergeRefs([ref, refs.setReference]); // this is to not block clicking and hovering outside
  // when the exit animation plays
  // and when on touch screen

  var overlayPointerEvents = status === 'open' || status === 'initial' ? 'all' : 'none';
  var interactionsFloatingProps = interactions.getFloatingProps();
  return /*#__PURE__*/React.createElement("div", {
    id: wrapperId,
    className: selectClass,
    onClick: onClick,
    suppressHydrationWarning: true
  }, /*#__PURE__*/React.createElement("div", _extends({
    ref: selectRef,
    id: id,
    className: selectElementClassName,
    role: "combobox",
    tabIndex: !disabled ? 0 : -1,
    "aria-disabled": disabled,
    "aria-invalid": invalid ? true : undefined,
    "aria-controls": interactionsFloatingProps.id,
    "aria-expanded": isExpanded,
    "aria-haspopup": "listbox",
    "data-status": status,
    suppressHydrationWarning: true
  }, interactions.getReferenceProps({
    // Handle keyboard
    onKeyDown: function onKeyDown(event) {
      if ((event.key === 'Enter' || event.key === ' ') && !disabled) {
        event.preventDefault();
        onOpenChange(!isExpanded);
      }
    }
  }), additionalProps), selectDisplayValue, /*#__PURE__*/React.createElement("div", {
    className: "sg-select-menu__element-icon"
  }, /*#__PURE__*/React.createElement(Icon, {
    type: "caret_down",
    size: ICON_SIZE_MAP[size],
    color: "icon-gray-70",
    "aria-hidden": true
  }))), isMounted && /*#__PURE__*/React.createElement(FloatingOverlay, {
    lockScroll: !isTouchScreen(),
    style: {
      zIndex: 1,
      pointerEvents: overlayPointerEvents
    }
  }, /*#__PURE__*/React.createElement(FloatingFocusManager, {
    context: context,
    modal: false,
    visuallyHiddenDismiss: true,
    order: ['reference', 'content'],
    initialFocus: -1
  }, /*#__PURE__*/React.createElement("div", _extends({
    ref: refs.setFloating,
    className: floatingContainerClassName,
    style: {
      position: floatingProps.strategy,
      top: (_floatingProps$y = floatingProps.y) !== null && _floatingProps$y !== void 0 ? _floatingProps$y : 0,
      left: (_floatingProps$x = floatingProps.x) !== null && _floatingProps$x !== void 0 ? _floatingProps$x : 0,
      minWidth: 120,
      width: 'max-content',
      maxWidth: 320,
      zIndex: 1,
      pointerEvents: 'auto'
    }
  }, interactionsFloatingProps, {
    "aria-labelledby": id,
    tabIndex: -1,
    "data-placement": floatingProps.placement,
    "aria-multiselectable": multiSelect
  }), /*#__PURE__*/React.createElement("div", {
    className: popupClassName,
    "data-placement": floatingProps.placement,
    tabIndex: activeIndex === null ? 0 : -1,
    role: "none"
  }, /*#__PURE__*/React.createElement("div", {
    className: popupContentClassName,
    role: "none"
  }, optionsElements))))));
});
SelectMenu.displayName = 'SelectMenu';
export default SelectMenu;