import _extends from "@babel/runtime/helpers/esm/extends";
import React, { useCallback, useState, useMemo, useEffect, useRef } from "react";
import classNames from "classnames";
import { OptionContent } from "./OptionContent/OptionContent";
import { StyledSelectForm, StyledSelectInput, StyledCheckbox, StyledRadioButton, StyledStartAdornment, StyledEndAdornment } from "./Styles";
import useForkRef from "../../utils/useForkRef";
import { Autocomplete, isOptionGroup } from "../Autocomplete";
import { Menu } from "../Menu/Menu";
export const Select = _ref => {
  let {
    type = "single",
    mode,
    target,
    options,
    selected = [],
    mixed = [],
    position = "bottom-start",
    onChange = () => null,
    placeholder,
    emptyAction = () => null,
    disableSearch = false,
    forceCloseMenu,
    selectClassName,
    keepSameOptionsOrder = false,
    onSelectOpen,
    onSelectClose,
    renderOption,
    handleDefaultOptionChange,
    preselectDefaultValue = type === "single",
    startAdornment,
    endAdornment,
    focusInput = false,
    disableVirtualization,
    ...prop
  } = _ref;
  if (disableSearch && (startAdornment || endAdornment)) {
    console.warn("Adornments are not visible when search bar is hidden");
  }
  const childNode = useRef();
  const elementRef = useRef(null);
  const handleRef = useForkRef(childNode, elementRef);
  const Tag = !target ? "div" : Menu;
  const formRef = useRef(null);
  const [open, setOpen] = useState(false);
  const selectedOptions = useMemo(() => selected instanceof Array ? selected : [selected], [selected]);
  const selectOptions = useMemo(() => {
    if (!options) {
      return [];
    }
    return options;
  }, [options]);
  const allOptionValues = useMemo(() => {
    return selectOptions.reduce((acc, option) => {
      if (!isOptionGroup(option)) {
        return [...acc, option.id];
      }
      const allGroupOptions = option.options.map(option => option.id);
      return [...acc, ...allGroupOptions];
    }, []);
  }, [selectOptions]);
  const mixedOptions = useRef(type === "multiple" && mixed.length ? mixed : []);
  const removeFromMixedOptions = useCallback(idsToRemove => {
    mixedOptions.current = mixedOptions.current.filter(mixedOption => !idsToRemove.includes(mixedOption));
  }, []);
  const isAllOptionsChecked = useMemo(() => allOptionValues.every(option => selectedOptions.includes(option)), [allOptionValues, selectedOptions]);
  const someOptionsChecked = useMemo(() => allOptionValues.some(option => selectedOptions.includes(option)), [allOptionValues, selectedOptions]);
  useEffect(() => {
    if (open && target || !target && focusInput) {
      var _childNode$current;
      childNode == null || (_childNode$current = childNode.current) == null || _childNode$current.focus();
    }
  }, [focusInput, open, target]);
  const handleChange = useCallback(selectedValue => {
    if (forceCloseMenu) {
      if (typeof onSelectClose === "function") onSelectClose();
      setOpen(false);
    }
    if (selectedValue !== undefined && selectedValue !== selected && !(selectedValue instanceof Array && selectedValue.includes(undefined))) {
      onChange(selectedValue);
      type === "multiple" && mixedOptions.current.length && removeFromMixedOptions(selectedValue);
    }
  }, [forceCloseMenu, selected, onSelectClose, onChange, type, removeFromMixedOptions]);
  const onClose = useCallback(() => {
    setOpen(false);
    if (onSelectClose) {
      onSelectClose();
    }
  }, [onSelectClose]);
  const onOpen = useCallback(() => {
    setOpen(true);
    if (onSelectOpen) {
      onSelectOpen();
    }
  }, [onSelectOpen]);
  const props = useMemo(() => {
    if (target) {
      return {
        menuClassName: classNames("c-select", selectClassName),
        onClose,
        onOpen,
        target,
        mode,
        open,
        position,
        onPopperOpen: () => {
          var _elementRef$current;
          return elementRef == null || (_elementRef$current = elementRef.current) == null ? void 0 : _elementRef$current.focus();
        }
      };
    }
    return {
      className: classNames("c-select", selectClassName)
    };
  }, [target, selectClassName, onClose, onOpen, mode, open, position]);
  const handleEmptyAction = useCallback(value => {
    var _formRef$current;
    emptyAction(value);
    if (forceCloseMenu) {
      setOpen(false);
    }
    (_formRef$current = formRef.current) == null || _formRef$current.reset();
  }, [emptyAction, forceCloseMenu]);
  const handleDefaultOptionChangeCallback = useCallback(() => {
    if (type === "multiple") {
      if (selectedOptions.length === allOptionValues.length) {
        if (typeof handleDefaultOptionChange === "function") {
          handleDefaultOptionChange();
        } else {
          onChange([]);
        }
      } else {
        if (typeof handleDefaultOptionChange === "function") {
          handleDefaultOptionChange();
        } else {
          onChange(allOptionValues);
        }
      }
    } else {
      if (typeof handleDefaultOptionChange === "function") {
        handleDefaultOptionChange();
      } else {
        onChange("");
      }
    }
    if (forceCloseMenu) {
      setOpen(false);
    }
  }, [onChange, type, forceCloseMenu, selectedOptions.length, allOptionValues, handleDefaultOptionChange]);
  const handleRenderOption = useCallback((option, props) => {
    if (typeof renderOption === "function") {
      return renderOption(option, props);
    }
    return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(OptionContent, {
      imageUrl: option.image,
      color: option.color,
      textColor: option.textColor,
      name: option.name,
      additionalInfo: option.additionalInfo
    }), option.id === null ? type === "multiple" ? /*#__PURE__*/React.createElement(StyledCheckbox, _extends({
      checked: isAllOptionsChecked,
      mixed: someOptionsChecked && !isAllOptionsChecked
    }, props)) : /*#__PURE__*/React.createElement(StyledRadioButton, _extends({
      checked: selectedOptions.length < 1 || !selectedOptions[0]
    }, props)) : type === "multiple" ? /*#__PURE__*/React.createElement(StyledCheckbox, _extends({
      mixed: mixedOptions.current.includes(option.id)
    }, props)) : /*#__PURE__*/React.createElement(StyledRadioButton, props));
  }, [isAllOptionsChecked, renderOption, type, someOptionsChecked, selectedOptions]);
  return /*#__PURE__*/React.createElement(Tag, props, /*#__PURE__*/React.createElement("div", null, !disableSearch ? /*#__PURE__*/React.createElement(StyledSelectForm, {
    ref: formRef
  }, startAdornment ? /*#__PURE__*/React.createElement(StyledStartAdornment, null, startAdornment) : null, /*#__PURE__*/React.createElement(StyledSelectInput, {
    ref: handleRef,
    placeholder: placeholder
  }), endAdornment ? /*#__PURE__*/React.createElement(StyledEndAdornment, null, endAdornment) : null) : null, /*#__PURE__*/React.createElement(Autocomplete, _extends({}, prop, {
    clearInputOnSelect: true,
    inputEl: childNode,
    handleEmptyAction: handleEmptyAction,
    selected: selected,
    handleChange: handleChange,
    renderOption: handleRenderOption,
    options: options,
    mixedOptions: mixedOptions.current,
    handleDefaultOptionChange: handleDefaultOptionChangeCallback,
    type: type,
    preselectDefaultValue: preselectDefaultValue,
    keepSameOptionsOrder: keepSameOptionsOrder,
    disableVirtualization: disableVirtualization
  }))));
};
Select.displayName = "Select";
//# sourceMappingURL=Select.js.map