"use strict";

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

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

var __assign = void 0 && (void 0).__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 __createBinding = void 0 && (void 0).__createBinding || (Object.create ? function (o, m, k, k2) {
  if (k2 === undefined) k2 = k;
  Object.defineProperty(o, k2, {
    enumerable: true,
    get: function get() {
      return m[k];
    }
  });
} : function (o, m, k, k2) {
  if (k2 === undefined) k2 = k;
  o[k2] = m[k];
});

var __setModuleDefault = void 0 && (void 0).__setModuleDefault || (Object.create ? function (o, v) {
  Object.defineProperty(o, "default", {
    enumerable: true,
    value: v
  });
} : function (o, v) {
  o["default"] = v;
});

var __importStar = void 0 && (void 0).__importStar || function (mod) {
  if (mod && mod.__esModule) return mod;
  var result = {};
  if (mod != null) for (var k in mod) {
    if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
  }

  __setModuleDefault(result, mod);

  return result;
};

var __rest = void 0 && (void 0).__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 = void 0 && (void 0).__spreadArray || function (to, from) {
  for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) {
    to[j] = from[i];
  }

  return to;
};

var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
  return mod && mod.__esModule ? mod : {
    "default": mod
  };
};

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Option = exports.SelectMemo = exports.SelectTag = exports.getCustomerSelectedIcon = exports.formateVal = exports.singleItemIcon = exports.multiItemSelectedIcon = exports.LIST_MAX_HEIGHT = exports.prefixCls = void 0;

var jsx_runtime_1 = require("react/jsx-runtime");

var React = __importStar(require("react"));

var rc_select_1 = __importStar(require("rc-select"));

Object.defineProperty(exports, "Option", {
  enumerable: true,
  get: function get() {
    return rc_select_1.Option;
  }
});

var useStaticCallback_1 = __importDefault(require("../../hooks/useStaticCallback"));

var classnames_1 = __importDefault(require("classnames"));

var findIndex_1 = __importDefault(require("lodash/findIndex"));

var filter_1 = __importDefault(require("lodash/filter"));

var checkbox_1 = require("../checkbox");

var icon_1 = __importDefault(require("../icon"));

var tag_1 = __importDefault(require("../tag"));

var virtualized_list_1 = __importDefault(require("../virtualized-list"));

require("./style/index.css");

exports.prefixCls = 'dmc-select';
exports.LIST_MAX_HEIGHT = 300;

var multiItemSelectedIcon = function multiItemSelectedIcon(props) {
  return jsx_runtime_1.jsx(checkbox_1.CheckboxMemo, {
    size: "compact",
    checked: props.isSelected,
    disabled: props.disabled
  }, void 0);
};

exports.multiItemSelectedIcon = multiItemSelectedIcon;
exports.singleItemIcon = jsx_runtime_1.jsx(icon_1["default"], {
  icon: "done-check",
  className: exports.prefixCls + "-item-option-state-icon"
}, void 0);

var formateVal = function formateVal(val, valueKey) {
  if (valueKey === void 0) {
    valueKey = 'value';
  }

  return (0, _typeof2["default"])(val) === 'object' ? Array.isArray(val) ? val.map(function (v) {
    return (0, _typeof2["default"])(v) === 'object' ? v[valueKey] : v;
  }) : [val[valueKey]] : [val];
};

exports.formateVal = formateVal;

var getCustomerSelectedIcon = function getCustomerSelectedIcon(menuItemSelectedIcon, isMulti) {
  return isMulti ? menuItemSelectedIcon || function (selectedProps) {
    return exports.multiItemSelectedIcon(selectedProps);
  } : menuItemSelectedIcon || exports.singleItemIcon;
};

exports.getCustomerSelectedIcon = getCustomerSelectedIcon;
exports.SelectTag = 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_runtime_1.jsx(tag_1["default"], {
    tag: label,
    closable: closable,
    onClickClose: onClose,
    color: color
  }, void 0);
});
var ViewItem = React.memo(function (_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;
  var selected = actualVal.includes(item[valueKey]);
  var itemCls = classnames_1["default"](exports.prefixCls + "-item", exports.prefixCls + "-item-option", className, (_b = {}, _b[exports.prefixCls + "-item-option-selected"] = selected, _b[exports.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]);
  return jsx_runtime_1.jsxs("div", __assign({
    style: __assign({}, style),
    className: itemCls,
    onClick: onClick
  }, {
    children: [isFlag && jsx_runtime_1.jsx("span", __assign({
      className: exports.prefixCls + "-item-option-state"
    }, {
      children: typeof customerSelectedIcon === 'function' ? customerSelectedIcon({
        isSelected: selected,
        disabled: item.disabled
      }) : customerSelectedIcon
    }), void 0), jsx_runtime_1.jsx("div", __assign({
      className: exports.prefixCls + "-item-option-content"
    }, {
      children: item[labelKey]
    }), void 0)]
  }), item[valueKey]);
});

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 = _c.onBlur,
      autoCreateItem = _c.autoCreateItem,
      addValFormatter = _c.addValFormatter,
      defaultValue = _c.defaultValue,
      onDropdownVisibleChange = _c.onDropdownVisibleChange,
      onPopupScroll = _c.onPopupScroll,
      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", "onBlur", "autoCreateItem", "addValFormatter", "defaultValue", "onDropdownVisibleChange", "onPopupScroll"]);

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

  var isControl = ('value' in props);
  var actualVal = isControl ? exports.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 allOptions = React.useRef([]);
  allOptions.current = autoCreateItem ? __spreadArray(__spreadArray([], options), 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_1["default"](exports.prefixCls + "-dropdown", dropdownClassName, (_a = {}, _a[exports.prefixCls + "-" + type + "-dropdown"] = type, _a));
  var selectCls = classnames_1["default"]((_b = {}, _b[exports.prefixCls + "-create-select-single"] = !isMulti && createAble, _b[exports.prefixCls + "-" + type] = type, _b[exports.prefixCls + "-" + size] = size, _b[exports.prefixCls + "-block"] = block, _b), className);
  var actualInputIcon = inputIcon || jsx_runtime_1.jsx(icon_1["default"], {
    icon: "arrow-down",
    className: exports.prefixCls + "-arrow-icon"
  }, void 0);
  var customerSelectedIcon = exports.getCustomerSelectedIcon(menuItemSelectedIcon, isMulti);

  var customerTagRender = tagRender || function (props) {
    return jsx_runtime_1.jsx(exports.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) {
    var currentOptions = value ? allOptions.current.filter(function (option) {
      return option[labelKey].includes(value);
    }) : 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);
  }, [labelKey, onSearch, createAble]);
  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_1["default"](exports.prefixCls + "-item", exports.prefixCls + "-item-option", exports.prefixCls + "-item-new-option");

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

    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_1["default"](__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_1["default"](__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 jsx_runtime_1.jsxs("div", __assign({
      className: newOptionCls,
      onClick: addOption
    }, {
      children: [jsx_runtime_1.jsx(icon_1["default"], {
        icon: "add",
        className: exports.prefixCls + "-item-option-state-icon"
      }, void 0), jsx_runtime_1.jsx("div", __assign({
        className: exports.prefixCls + "-item-new-option-content"
      }, {
        children: getNewOptionTemp ? getNewOptionTemp(filterVal) : filterVal
      }), void 0)]
    }), "newOption");
  }, [addOption, filterVal, getNewOptionTemp, newOptionCls]);

  var _dropdownRender = function _dropdownRender(menu) {
    // step1: loading status check
    if (loading) {
      return jsx_runtime_1.jsx("div", __assign({
        className: exports.prefixCls + "-dropdown-loading"
      }, {
        children: jsx_runtime_1.jsx(icon_1["default"], {
          icon: "loading"
        }, void 0)
      }), void 0);
    } // step2: render


    if (filterOptions.length === 0 && createAble) {
      return jsx_runtime_1.jsx(jsx_runtime_1.Fragment, {
        children: addOptionNode
      }, void 0);
    }

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


    var _scrollTop = actualOpen ? undefined : 0;

    return jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, {
      children: [jsx_runtime_1.jsx(virtualized_list_1["default"], {
        scrollTop: _scrollTop,
        data: filterOptions,
        ItemView: ViewItem,
        noRowsRenderer: function noRowsRenderer() {
          return notFoundContent;
        },
        maxHeight: exports.LIST_MAX_HEIGHT,
        itemViewProps: itemExtraProps,
        type: type,
        onScroll: onPopupScroll
      }, void 0), showCreate && addOptionNode]
    }, void 0);
  };

  var _onDeselect = React.useCallback(function (value, option) {
    var newIndex = findIndex_1["default"](newOptions, {
      value: value
    });

    if (newIndex > -1) {
      setNewOptions(function (prevOptions) {
        return filter_1["default"](prevOptions, function (option) {
          return option[valueKey] !== value;
        });
      });
      setFilterOptions(filter_1["default"](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]);

  var _blur = useStaticCallback_1["default"](function (v) {
    if (!actualOpen) {
      setFilterVal('');
      setFilterOptions(allOptions.current);
    }

    onBlur && onBlur(v);
  });

  var searchAble = showSearch || createAble;
  return jsx_runtime_1.jsx(rc_select_1["default"], __assign({}, restProps, {
    prefixCls: exports.prefixCls,
    className: selectCls,
    inputIcon: 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
  }), void 0);
};

var defaultProps = {
  createAble: false,
  labelKey: 'label',
  valueKey: 'value',
  options: [],
  autoCreateItem: true
};
Select.defaultProps = defaultProps;
var SelectMemo = React.memo(Select);
exports.SelectMemo = SelectMemo;
SelectMemo.displayName = 'SelectMemo';
Select.displayName = 'Select';
exports["default"] = Select;

