import _typeof from "@babel/runtime/helpers/esm/typeof";

var __assign = this && this.__assign || function () {
  __assign = Object.assign || function (t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
      s = arguments[i];

      for (var p in s) {
        if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
      }
    }

    return t;
  };

  return __assign.apply(this, arguments);
};

var __rest = this && this.__rest || function (s, e) {
  var t = {};

  for (var p in s) {
    if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  }

  if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
    if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  }
  return t;
};

var __spreadArray = this && this.__spreadArray || function (to, from) {
  for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) {
    to[j] = from[i];
  }

  return to;
};

import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
/* eslint-disable @typescript-eslint/no-explicit-any */

import * as React from 'react';
import RcSelect, { Option } from 'rc-select'; // import useStaticCallback from '@/hooks/useStaticCallback';

import classNames from 'classnames';
import findIndex from 'lodash/findIndex';
import filter from 'lodash/filter';
import isEmpty from 'lodash/isEmpty';
import { CheckboxMemo } from "../checkbox";
import Icon from "../icon";
import Tag from "../tag";
import VirtualizedList from "../virtualized-list";
import "./style/index.css";
import Tooltip from "../tooltip";
export var prefixCls = 'dmc-select';
export var LIST_MAX_HEIGHT = 300;
export var multiItemSelectedIcon = function multiItemSelectedIcon(props) {
  return _jsx(CheckboxMemo, {
    size: "compact",
    checked: props.isSelected,
    disabled: props.disabled
  }, void 0);
};
export var singleItemIcon = _jsx(Icon, {
  icon: "done-check",
  className: prefixCls + "-item-option-state-icon"
}, void 0);
export var formateVal = function formateVal(val, valueKey) {
  if (valueKey === void 0) {
    valueKey = 'value';
  }

  return _typeof(val) === 'object' ? Array.isArray(val) ? val.map(function (v) {
    return _typeof(v) === 'object' ? v[valueKey] : v;
  }) : [val[valueKey]] : [val];
};
export var getCustomerSelectedIcon = function getCustomerSelectedIcon(menuItemSelectedIcon, isMulti) {
  return isMulti ? menuItemSelectedIcon || function (selectedProps) {
    return multiItemSelectedIcon(selectedProps);
  } : menuItemSelectedIcon || singleItemIcon;
};
export var SelectTag = /*#__PURE__*/React.memo(function (props) {
  var label = props.label,
      closable = props.closable,
      onClose = props.onClose,
      _a = props.color,
      color = _a === void 0 ? 'grey-blue-400' : _a;
  return _jsx(Tag, {
    tag: label,
    closable: closable,
    onClickClose: onClose,
    color: color
  }, void 0);
});

var ViewItem = function ViewItem(_a) {
  var _b;

  var item = _a.item,
      className = _a.className,
      style = _a.style,
      labelKey = _a.labelKey,
      valueKey = _a.valueKey,
      actualVal = _a.actualVal,
      onSelectChange = _a.onSelectChange,
      customerSelectedIcon = _a.customerSelectedIcon,
      isMulti = _a.isMulti,
      showTip = _a.showTip,
      tipPlacement = _a.tipPlacement;
  var selected = actualVal.includes(item[valueKey]);
  var itemCls = classNames(prefixCls + "-item", prefixCls + "-item-option", className, (_b = {}, _b[prefixCls + "-item-option-selected"] = selected, _b[prefixCls + "-item-option-disabled"] = item.disabled, _b));
  var isFlag = selected && !isMulti || isMulti;
  var onClick = React.useCallback(function () {
    if (item.disabled) {
      return;
    }

    onSelectChange(item);
  }, [item, onSelectChange]);

  var dom = _jsx("div", __assign({
    style: __assign({}, style),
    className: itemCls,
    onClick: onClick
  }, {
    children: _jsxs(_Fragment, {
      children: [isFlag && _jsx("span", __assign({
        className: prefixCls + "-item-option-state"
      }, {
        children: typeof customerSelectedIcon === 'function' ? customerSelectedIcon({
          isSelected: selected,
          disabled: item.disabled
        }) : customerSelectedIcon
      }), void 0), _jsx("div", __assign({
        className: prefixCls + "-item-option-content"
      }, {
        children: item[labelKey]
      }), void 0)]
    }, void 0)
  }), item[valueKey]);

  return _jsx(_Fragment, {
    children: showTip ? _jsx(Tooltip, __assign({
      overlay: item[labelKey],
      placement: tipPlacement
    }, {
      children: dom
    }), void 0) : dom
  }, void 0);
};

var Select = function Select(props) {
  var _a, _b;

  var _c = props,
      type = _c.type,
      size = _c.size,
      className = _c.className,
      mode = _c.mode,
      menuItemSelectedIcon = _c.menuItemSelectedIcon,
      inputIcon = _c.inputIcon,
      dropdownClassName = _c.dropdownClassName,
      tagRender = _c.tagRender,
      labelKey = _c.labelKey,
      valueKey = _c.valueKey,
      options = _c.options,
      value = _c.value,
      onSearch = _c.onSearch,
      dropdownRender = _c.dropdownRender,
      onChange = _c.onChange,
      notFoundContent = _c.notFoundContent,
      open = _c.open,
      defaultOpen = _c.defaultOpen,
      showSearch = _c.showSearch,
      onSelect = _c.onSelect,
      loading = _c.loading,
      getNewOptionTemp = _c.getNewOptionTemp,
      block = _c.block,
      onDeselect = _c.onDeselect,
      createAble = _c.createAble,
      // onBlur,
  autoCreateItem = _c.autoCreateItem,
      addValFormatter = _c.addValFormatter,
      defaultValue = _c.defaultValue,
      onDropdownVisibleChange = _c.onDropdownVisibleChange,
      onPopupScroll = _c.onPopupScroll,
      allowClear = _c.allowClear,
      clearIcon = _c.clearIcon,
      showTip = _c.showTip,
      tipPlacement = _c.tipPlacement,
      customSearchFilter = _c.customSearchFilter,
      dynamicRowHeight = _c.dynamicRowHeight,
      restProps = __rest(_c, ["type", "size", "className", "mode", "menuItemSelectedIcon", "inputIcon", "dropdownClassName", "tagRender", "labelKey", "valueKey", "options", "value", "onSearch", "dropdownRender", "onChange", "notFoundContent", "open", "defaultOpen", "showSearch", "onSelect", "loading", "getNewOptionTemp", "block", "onDeselect", "createAble", "autoCreateItem", "addValFormatter", "defaultValue", "onDropdownVisibleChange", "onPopupScroll", "allowClear", "clearIcon", "showTip", "tipPlacement", "customSearchFilter", "dynamicRowHeight"]);

  var _d = React.useState(defaultValue ? [defaultValue] : []),
      unConTrolVal = _d[0],
      setUnTrolVal = _d[1];

  var isControl = ('value' in props);
  var actualVal = isControl ? formateVal(!value && value !== 0 ? [] : value) : unConTrolVal;

  var _e = React.useState(open || defaultOpen),
      actualOpen = _e[0],
      setOpen = _e[1];

  var _f = React.useState(''),
      filterVal = _f[0],
      setFilterVal = _f[1];

  var _g = React.useState([]),
      newOptions = _g[0],
      setNewOptions = _g[1];

  var _h = React.useState(false),
      showCreate = _h[0],
      setShowCreate = _h[1];

  var _allowClear = React.useMemo(function () {
    return actualVal.length ? allowClear : false;
  }, [actualVal, allowClear]);

  var _clearIcon = clearIcon || _jsx(Icon, {
    icon: "clear",
    className: prefixCls + "-arrow-icon"
  }, void 0);

  var allOptions = React.useRef([]);
  allOptions.current = React.useMemo(function () {
    return autoCreateItem ? __spreadArray(__spreadArray([], options), newOptions) : options;
  }, [autoCreateItem, newOptions, options]);

  var _j = React.useState(allOptions.current),
      filterOptions = _j[0],
      setFilterOptions = _j[1];

  var isMulti = mode === 'multiple';
  React.useEffect(function () {
    setFilterOptions(allOptions.current);
  }, [options]); // eslint-disable-next-line @typescript-eslint/no-explicit-any

  var selectRef = React.useRef(null);
  var dropdownCls = classNames(prefixCls + "-dropdown", dropdownClassName, (_a = {}, _a[prefixCls + "-" + type + "-dropdown"] = type, _a));
  var selectCls = classNames((_b = {}, _b[prefixCls + "-create-select-single"] = !isMulti && createAble, _b[prefixCls + "-" + type] = type, _b[prefixCls + "-" + size] = size, _b[prefixCls + "-block"] = block, _b), className);

  var actualInputIcon = inputIcon || _jsx(Icon, {
    icon: "arrow-down",
    className: prefixCls + "-arrow-icon"
  }, void 0);

  var customerSelectedIcon = getCustomerSelectedIcon(menuItemSelectedIcon, isMulti);

  var customerTagRender = tagRender || function (props) {
    return _jsx(SelectTag, __assign({}, props, {
      onClose: function onClose() {
        return onSelectChange(props);
      }
    }), void 0);
  };

  var onSelectChange = React.useCallback(function (item) {
    var value = item[valueKey];
    var val = isMulti ? actualVal.includes(value) ? actualVal.filter(function (v) {
      return v !== value;
    }) : __spreadArray(__spreadArray([], actualVal), [value]) : [value];
    setUnTrolVal(val);
    setFilterOptions(allOptions.current);
    onSelect && onSelect(value, item);
    onChange && onChange(isMulti ? val : value, allOptions.current.filter(function (v) {
      return val.includes(v[valueKey]);
    }));
    !mode && setOpen(false);
  }, [actualVal, isMulti, mode, onChange, onSelect, valueKey]);
  var onInputSearch = React.useCallback(function (value) {
    try {
      var filterFunc = function filterFunc() {
        var _a;

        return (_a = customSearchFilter === null || customSearchFilter === void 0 ? void 0 : customSearchFilter(value, allOptions.current)) !== null && _a !== void 0 ? _a : allOptions.current.filter(function (option) {
          var _a, _b, _c, _d;

          if (typeof option[labelKey] === 'string') {
            return option[labelKey].includes(value);
          }

          if (_typeof(option[labelKey]) === 'object' && ((_b = (_a = option[labelKey]) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b.children) && typeof ((_d = (_c = option[labelKey]) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.children) === 'string') {
            return option[labelKey].props.children.includes(value);
          }

          console.error("Custom \u3010" + option[labelKey] + "\u3011 can't pass the filter. use \"customSearchFilter\" instead");
          return false;
        });
      };

      var currentOptions = value ? filterFunc() : allOptions.current; // 如果没有完全匹配，则为模糊搜索的结果
      // 此时如果是create able，需要新建标签

      var show = createAble && value && !allOptions.current.find(function (option) {
        return value === option[labelKey];
      });
      setShowCreate(!!show);
      onSearch && onSearch(value);
      setFilterOptions(currentOptions);
      setFilterVal(value);
    } catch (error) {
      console.error(error);
    }
  }, [labelKey, onSearch, createAble, customSearchFilter]);
  var itemExtraProps = React.useMemo(function () {
    return {
      labelKey: labelKey,
      valueKey: valueKey,
      actualVal: actualVal,
      onSelectChange: onSelectChange,
      customerSelectedIcon: customerSelectedIcon,
      isMulti: isMulti
    };
  }, [actualVal, customerSelectedIcon, isMulti, labelKey, onSelectChange, valueKey]);
  var newOptionCls = classNames(prefixCls + "-item", prefixCls + "-item-option", prefixCls + "-item-new-option");

  var _onChange = React.useCallback(function (value, option) {
    var _a; // clear


    if (isEmpty(value)) {
      setUnTrolVal([]);
      onChange && onChange(value, option);
      return;
    }

    var onlyValue = value[value.length - 1];
    var onlyOpt = option[option.length - 1] || option;
    var newOption = {
      label: onlyValue,
      value: onlyValue,
      key: onlyValue
    };
    var val = isMulti ? value : filterVal ? [filterVal] : onlyValue ? [onlyValue] : [];
    var opt = isMulti ? option : filterVal ? allOptions.current.filter(function (it) {
      return it[valueKey] === filterVal;
    }) : onlyOpt ? [onlyOpt] : [];
    setUnTrolVal(val);
    setNewOptions(function (prevOptions) {
      return filter(__spreadArray(__spreadArray([], prevOptions), [newOption]), function (option) {
        return !!option[valueKey];
      });
    });
    setFilterOptions(__spreadArray(__spreadArray([], allOptions.current), [newOption]));

    if (!isMulti) {
      setOpen(false);
      (_a = selectRef.current) === null || _a === void 0 ? void 0 : _a.blur();
    }

    onSelect && onSelect(value[value.length - 1], onlyOpt);
    onChange && onChange(val, opt);
  }, [filterVal, isMulti, onChange, onSelect, valueKey]);

  var addOption = React.useCallback(function () {
    var _a;

    var v = addValFormatter ? addValFormatter(filterVal) : filterVal;
    if (v === undefined || v === null) return;
    var newOption = {
      label: filterVal,
      value: v,
      key: filterVal
    };
    var val = isMulti ? __spreadArray(__spreadArray([], actualVal), [v]) : [v];

    var opt = __spreadArray(__spreadArray([], allOptions.current.filter(function (it) {
      return val.includes(it[valueKey]);
    })), [newOption]);

    setUnTrolVal(val);
    setNewOptions(function (prevOptions) {
      return filter(__spreadArray(__spreadArray([], prevOptions), [newOption]), function (option) {
        return !!option[valueKey];
      });
    });
    setFilterOptions(__spreadArray(__spreadArray([], allOptions.current), [newOption]));

    if (!isMulti) {
      setOpen(false);
      (_a = selectRef.current) === null || _a === void 0 ? void 0 : _a.blur();
    }

    onSelect && onSelect(filterVal, newOption);
    onChange && onChange(isMulti ? val : val[0], opt);
  }, [actualVal, addValFormatter, filterVal, isMulti, onChange, onSelect, valueKey]);
  var addOptionNode = React.useMemo(function () {
    return _jsxs("div", __assign({
      className: newOptionCls,
      onClick: addOption
    }, {
      children: [_jsx(Icon, {
        icon: "add",
        className: prefixCls + "-item-option-state-icon"
      }, void 0), _jsx("div", __assign({
        className: prefixCls + "-item-new-option-content"
      }, {
        children: getNewOptionTemp ? getNewOptionTemp(filterVal) : filterVal
      }), void 0)]
    }), "newOption");
  }, [addOption, filterVal, getNewOptionTemp, newOptionCls]);

  var _dropdownRender = React.useCallback(function (menu) {
    // step1: loading status check
    if (loading) {
      return _jsx("div", __assign({
        className: prefixCls + "-dropdown-loading"
      }, {
        children: _jsx(Icon, {
          icon: "loading"
        }, void 0)
      }), void 0);
    } // step2: render


    if (filterOptions.length === 0 && createAble) {
      return _jsx(_Fragment, {
        children: addOptionNode
      }, void 0);
    }

    if (dropdownRender) {
      return _jsxs(_Fragment, {
        children: [dropdownRender(menu), showCreate && addOptionNode]
      }, void 0);
    } // 每次打开始终回到顶部，解决虚拟滚动留白的问题


    var _scrollTop = actualOpen ? undefined : 0; // fix muti search item need click double issue


    var renderRedirect = isMulti && showSearch;
    return _jsxs(_Fragment, {
      children: [renderRedirect ? _jsx("div", __assign({
        className: prefixCls + "-dropdown-no-virtual"
      }, {
        children: filterOptions.map(function (item, index) {
          return _jsx(ViewItem, __assign({
            item: item
          }, itemExtraProps, {
            showTip: showTip,
            tipPlacement: tipPlacement,
            index: index,
            className: "",
            style: {}
          }), item[valueKey]);
        })
      }), void 0) : _jsx("div", {
        children: _jsx(VirtualizedList, {
          scrollTop: _scrollTop,
          data: filterOptions,
          ItemView: function ItemView(rest) {
            return _jsx(ViewItem, __assign({
              showTip: showTip,
              tipPlacement: tipPlacement
            }, rest), void 0);
          },
          dynamicRowHeight: dynamicRowHeight,
          noRowsRenderer: function noRowsRenderer() {
            return notFoundContent;
          },
          maxHeight: LIST_MAX_HEIGHT,
          itemViewProps: itemExtraProps,
          type: type,
          onScroll: onPopupScroll
        }, void 0)
      }, void 0), showCreate && addOptionNode]
    }, void 0);
  }, [actualOpen, addOptionNode, createAble, dropdownRender, dynamicRowHeight, filterOptions, isMulti, itemExtraProps, loading, notFoundContent, onPopupScroll, showCreate, showSearch, showTip, tipPlacement, type, valueKey]);

  var _onDeselect = React.useCallback(function (value, option) {
    var newIndex = findIndex(newOptions, {
      value: value
    });

    if (newIndex > -1) {
      setNewOptions(function (prevOptions) {
        return filter(prevOptions, function (option) {
          return option[valueKey] !== value;
        });
      });
      setFilterOptions(filter(allOptions.current, function (option) {
        return option[valueKey] !== value;
      }));
    }

    onDeselect && onDeselect(value, option);
  }, [newOptions, onDeselect, valueKey]);

  var _onDropdownVisibleChange = React.useCallback(function (open) {
    setOpen(open);
    onDropdownVisibleChange && onDropdownVisibleChange(open);
  }, [onDropdownVisibleChange, setOpen]); // const _blur = useStaticCallback((v) => {
  //   if (!actualOpen) {
  //     setFilterVal('');
  //     setFilterOptions(allOptions.current);
  //   }
  //   onBlur && onBlur(v);
  // });


  var searchAble = showSearch || createAble;
  return _jsx(_Fragment, {
    children: _jsx(RcSelect, __assign({}, restProps, {
      prefixCls: prefixCls,
      className: selectCls,
      suffixIcon: actualInputIcon,
      dropdownClassName: dropdownCls,
      mode: mode,
      tagRender: customerTagRender,
      menuItemSelectedIcon: menuItemSelectedIcon !== null && menuItemSelectedIcon !== void 0 ? menuItemSelectedIcon : customerSelectedIcon,
      value: actualVal,
      open: actualOpen,
      options: allOptions.current,
      onSearch: searchAble ? onInputSearch : undefined,
      showSearch: searchAble,
      onDeselect: _onDeselect,
      onChange: _onChange,
      onDropdownVisibleChange: _onDropdownVisibleChange,
      loading: loading,
      dropdownRender: _dropdownRender,
      // onBlur={_blur}
      ref: selectRef,
      allowClear: _allowClear,
      clearIcon: _clearIcon
    }), void 0)
  }, void 0);
};

var defaultProps = {
  createAble: false,
  labelKey: 'label',
  valueKey: 'value',
  options: [],
  autoCreateItem: true
};
Select.defaultProps = defaultProps;
var SelectMemo = /*#__PURE__*/React.memo(Select);
SelectMemo.displayName = 'SelectMemo';
export { SelectMemo, Option };
Select.displayName = 'Select';
export default Select;

