import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import React, { useState, useCallback, useRef } from 'react';
import arrayTreeFilter from 'array-tree-filter';
import classNames from 'classnames';
import MutipleDropdown from './mutiple-dropdown-node';
import Select from '../select';
import RcCascader from '../components/rc-cascader';
import KeyCode from '../components/rc-util/KeyCode';
import { ConfigContext } from '../config-provider/context';
import Input from '../input';
import { Icons } from '../components';
import { replaceElement } from '../utils/ReactNodeValidate';
import { scrollInfiniteFun } from '../select/scrollInfinite';
import { getSelectOpts, isReadOnly } from './_util'; // @ts-ignore

import loadingGif from '../spin/gif/loading-basic-gray.gif';
var DownLine = Icons.DownLine,
    RightLine = Icons.RightLine,
    CloseFill = Icons.CloseFill;

function getFieldNames(_ref) {
  var fieldNames = _ref.fieldNames;
  return fieldNames;
}

function getFilledFieldNames(props) {
  var fieldNames = getFieldNames(props) || {};
  var names = {
    children: fieldNames.children || 'children',
    label: fieldNames.label || 'label',
    value: fieldNames.value || 'value'
  };
  return names;
}

function highlightKeyword(str, keyword, prefixCls) {
  return str.split(keyword).map(function (node, index) {
    return index === 0 ? node : [/*#__PURE__*/React.createElement("span", {
      className: "".concat(prefixCls, "-menu-item-keyword"),
      key: "seperator"
    }, keyword), node];
  });
} // 搜索时 拍平树


function flattenTree(options, props) {
  var ancestor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
  var names = getFilledFieldNames(props);
  var flattenOptions = [];
  var childrenName = names.children;
  options.forEach(function (option) {
    var path = ancestor.concat(option);

    if (props.changeOnSelect || !option[childrenName] || !option[childrenName].length) {
      flattenOptions.push(path);
    }

    if (option[childrenName]) {
      flattenOptions = flattenOptions.concat(flattenTree(option[childrenName], props, path));
    }
  });
  return flattenOptions;
}

var Cascader = function Cascader(props) {
  var _classNames, _classNames3;

  var onChange = props.onChange,
      placeholder = props.placeholder,
      className = props.className,
      disabled = props.disabled,
      autoFocus = props.autoFocus,
      suffixIcon = props.suffixIcon,
      defaultValue = props.defaultValue,
      pickerTitle = props.pickerTitle,
      showPickerTitle = props.showPickerTitle,
      _props$popupVisible = props.popupVisible,
      popupVisible = _props$popupVisible === void 0 ? false : _props$popupVisible,
      multiple = props.multiple,
      collapse = props.collapse,
      dropdownMenuColumnWidth = props.dropdownMenuColumnWidth,
      dropdownMenuColumnStyle = props.dropdownMenuColumnStyle,
      onPopupVisibleChange = props.onPopupVisibleChange,
      getPopupContainer = props.getPopupContainer,
      showSearch = props.showSearch,
      _props$readOnly = props.readOnly,
      readOnly = _props$readOnly === void 0 ? true : _props$readOnly,
      outerInputValue = props.inputValue,
      size = props.size,
      dropdownRender = props.dropdownRender,
      dropdownFooterContent = props.dropdownFooterContent,
      style = props.style,
      allowClear = props.allowClear,
      onPopupScroll = props.onPopupScroll,
      scrollInfinite = props.scrollInfinite,
      infiniteHasMore = props.infiniteHasMore,
      loadData = props.loadData,
      tagRender = props.tagRender,
      _props$maxTagCount = props.maxTagCount,
      maxTagCount = _props$maxTagCount === void 0 ? 1 : _props$maxTagCount,
      maxTagTextLength = props.maxTagTextLength,
      onInputChange = props.onInputChange,
      restProps = _objectWithoutProperties(props, ["onChange", "placeholder", "className", "disabled", "autoFocus", "suffixIcon", "defaultValue", "pickerTitle", "showPickerTitle", "popupVisible", "multiple", "collapse", "dropdownMenuColumnWidth", "dropdownMenuColumnStyle", "onPopupVisibleChange", "getPopupContainer", "showSearch", "readOnly", "inputValue", "size", "dropdownRender", "dropdownFooterContent", "style", "allowClear", "onPopupScroll", "scrollInfinite", "infiniteHasMore", "loadData", "tagRender", "maxTagCount", "maxTagTextLength", "onInputChange"]);

  var _React$useContext = React.useContext(ConfigContext),
      contextSize = _React$useContext.size,
      getPrefixClassName = _React$useContext.getPrefixClassName,
      getCtxPopupContainer = _React$useContext.getPopupContainer;

  var endSize = size || contextSize;
  var prefixCls = getPrefixClassName('cascader'); // const rcCascaderPrefixCls = classNames(prefixCls, {
  //   [`${prefixCls}-size`]: size
  // })
  // console.log('rcCascaderPrefixCls..', rcCascaderPrefixCls)

  var _useState = useState(outerInputValue),
      _useState2 = _slicedToArray(_useState, 2),
      inputValue = _useState2[0],
      setInputValue = _useState2[1];

  var _useState3 = useState(props.value || props.defaultValue),
      _useState4 = _slicedToArray(_useState3, 2),
      value = _useState4[0],
      setRcVal = _useState4[1];

  var _useState5 = useState(popupVisible),
      _useState6 = _slicedToArray(_useState5, 2),
      selectVisible = _useState6[0],
      setSelectVisible = _useState6[1];

  var _useState7 = useState(false),
      _useState8 = _slicedToArray(_useState7, 2),
      inputFocused = _useState8[0],
      setInputFocused = _useState8[1];

  var inputRef = useRef(null); // const mutipleTreeValsRef = useRef(value);

  var clearSelectionTimeout;

  if ('value' in props && props.value !== value) {
    setRcVal(props.value); // mutipleTreeValsRef.current = props.value;
  }

  if ('inputValue' in props && outerInputValue !== inputValue) {
    setInputValue(outerInputValue); // mutipleTreeValsRef.current = props.value;
  }

  if ('popupVisible' in props && props.popupVisible !== selectVisible) {
    setSelectVisible(!!props.popupVisible);
  }

  React.useEffect(function () {
    return function () {
      if (clearSelectionTimeout) {
        clearTimeout(clearSelectionTimeout);
      }
    };
  }, []); // 搜索数据

  var flattenOptions = showSearch ? flattenTree(props.options, props) : undefined;
  var pickerCls = classNames("".concat(prefixCls, "-picker"), (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-picker-with-value"), inputValue), _defineProperty(_classNames, "".concat(prefixCls, "-picker-disabled"), disabled), _defineProperty(_classNames, "".concat(prefixCls, "-picker-show-search"), !!showSearch), _defineProperty(_classNames, "".concat(prefixCls, "-picker-focused"), inputFocused), _classNames), className);

  var renderEmpty = function renderEmpty() {
    return /*#__PURE__*/React.createElement("div", {
      className: "".concat(prefixCls, "-no-data")
    }, "\u6682\u65E0\u6570\u636E");
  }; // keep value when filtering


  var keepFilteredValueField = '__KEEP_FILTERED_OPTION_VALUE'; // 搜索的方法 数据处理；

  function defaultFilterOption(val, path, arr) {
    return path.some(function (option) {
      return option[arr.label].indexOf(val) > -1;
    });
  }

  function defaultRenderFilteredOption(val, path, prefixClss, arr) {
    return path.map(function (option, index) {
      var label = option[arr.label];
      var node = label.indexOf(inputValue) > -1 ? highlightKeyword(label, val, prefixClss) : label;
      return index === 0 ? node : [' / ', node];
    });
  }

  function getEmptyNode(renderEmptys, arr, notFoundContent) {
    var _ref2;

    return _ref2 = {}, _defineProperty(_ref2, arr.value, 'NOT_FOUND'), _defineProperty(_ref2, arr.label, notFoundContent || renderEmptys('Cascader')), _defineProperty(_ref2, "disabled", true), _defineProperty(_ref2, "isEmptyNode", true), _ref2;
  }

  function defaultSortFilteredOption(a, b, val, arr) {
    function callback(elem) {
      return elem[arr.label].indexOf(val) > -1;
    }

    return a.findIndex(callback) - b.findIndex(callback);
  } // We limit the filtered item count by default


  var defaultLimit = 50; // 过滤数据

  var generateFilteredOptions = function generateFilteredOptions(prefixClss, renderEmptys) {
    var notFoundContent = props.notFoundContent;
    var arr = getFilledFieldNames(props);
    var _showSearch$filter = showSearch.filter,
        filter = _showSearch$filter === void 0 ? defaultFilterOption : _showSearch$filter,
        _showSearch$render = showSearch.render,
        render = _showSearch$render === void 0 ? defaultRenderFilteredOption : _showSearch$render,
        _showSearch$sort = showSearch.sort,
        sort = _showSearch$sort === void 0 ? defaultSortFilteredOption : _showSearch$sort,
        _showSearch$limit = showSearch.limit,
        limit = _showSearch$limit === void 0 ? defaultLimit : _showSearch$limit; // Limit the filter if needed

    var filtered;

    if (limit > 0) {
      filtered = [];
      var matchCount = 0; // Perf optimization to filter items only below the limit

      flattenOptions.some(function (path) {
        var match = filter(inputValue, path, arr);

        if (match) {
          filtered.push(path);
          matchCount += 1;
        }

        return matchCount >= limit;
      });
    } else {
      filtered = flattenOptions.filter(function (path) {
        return filter(inputValue, path, arr);
      });
    }

    filtered = filtered.sort(function (a, b) {
      return sort(a, b, inputValue, arr);
    });

    if (filtered.length > 0) {
      var field = arr.value === arr.label ? keepFilteredValueField : arr.value;
      return filtered.map(function (path) {
        var _ref3;

        return _ref3 = {
          klein__IS_FILTERED_OPTION: true,
          path: path
        }, _defineProperty(_ref3, field, path.map(function (o) {
          return o[arr.value];
        })), _defineProperty(_ref3, arr.label, render(inputValue, path, prefixClss, arr)), _defineProperty(_ref3, "disabled", path.some(function (o) {
          return !!o.disabled;
        })), _defineProperty(_ref3, "isEmptyNode", true), _defineProperty(_ref3, "checked", props.hasChecked), _ref3;
      });
    }

    return [getEmptyNode(renderEmptys, arr, notFoundContent)];
  };

  var handlePopupVisibleChange = function handlePopupVisibleChange(flag) {
    if (!('popupVisible' in props)) {
      setSelectVisible(flag);
      setInputFocused(flag);
      setInputValue(function (pre) {
        return pre;
      });
    }

    onPopupVisibleChange === null || onPopupVisibleChange === void 0 ? void 0 : onPopupVisibleChange(flag);
  }; // 搜索 过滤数据


  var handleInputChange = function handleInputChange(e) {
    if (!popupVisible) {
      handlePopupVisibleChange(true);
    }

    setInputVal(e.target.value);
  }; // 清除选中值


  var clearSelection = function clearSelection(e) {
    e.preventDefault();
    e.stopPropagation();

    if (!inputValue) {
      handlePopupVisibleChange(false);
      clearSelectionTimeout = setTimeout(function () {
        setValue([]);
      }, 200);
    } else {
      setInputVal('');
    }
  }; // render clear icon


  var renderClearIcon = ((value === null || value === void 0 ? void 0 : value.length) > 0 || (inputValue === null || inputValue === void 0 ? void 0 : inputValue.length) > 0) && allowClear ? /*#__PURE__*/React.createElement(CloseFill, {
    className: "".concat(prefixCls, "-picker-clear"),
    onClick: clearSelection
  }) : null;
  var options = props.options;
  var arrPd = getFilledFieldNames(props);

  if (options && options.length > 0) {
    // console.log(options, '----options'); // szp
    if (inputValue && showSearch) {
      options = generateFilteredOptions(prefixCls, renderEmpty);
    }
  } else {
    options = [getEmptyNode(renderEmpty, arrPd, props.notFoundContent)];
  }

  var handleInputBlur = function handleInputBlur() {
    setInputFocused(false);
  };

  var handleInputClick = function handleInputClick(e) {
    // Prevent `Trigger` behaviour.
    if (inputFocused || popupVisible) {
      e.stopPropagation();
    }
  }; // 阻止回退键的删除事件 在showSearch 属性


  var handleKeyDown = function handleKeyDown(e) {
    if (e.keyCode === KeyCode.BACKSPACE || e.keyCode === KeyCode.SPACE) {
      e.stopPropagation();
    }
  };

  var setValue = function setValue(arrVal) {
    var selectedOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];

    if (!('value' in props)) {
      setRcVal(arrVal);
    } // if (mutipleValues) {
    //   onChange?.(mutipleValues);
    //   return;
    // }


    onChange === null || onChange === void 0 ? void 0 : onChange(arrVal, selectedOptions);
  };

  var setInputVal = function setInputVal(val) {
    if (typeof outerInputValue === 'undefined') {
      setInputValue(val);
    }

    onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange(val);
  };

  var handleChange = function handleChange(values, selectedOptions) {
    setInputValue(''); // 搜索过滤的时候

    if (selectedOptions[0].klein__IS_FILTERED_OPTION) {
      var unwrappedValue = selectedOptions[0][keepFilteredValueField] === undefined ? values[0] : selectedOptions[0][keepFilteredValueField];
      var unwrappedSelectedOptions = selectedOptions[0].path;
      setValue(unwrappedValue, unwrappedSelectedOptions);
      return;
    }

    setValue(values, selectedOptions);
  };

  var defaultDisplayRender = function defaultDisplayRender(label) {
    return label.join(' / ');
  };

  var getLabel = function getLabel() {
    var _props$displayRender = props.displayRender,
        displayRender = _props$displayRender === void 0 ? defaultDisplayRender : _props$displayRender;

    if (value) {
      // 未选择的时候 可能是undefined
      var arrs = getFilledFieldNames(props);
      var unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
      var selectedOptions = arrayTreeFilter(props.options, function (o, level) {
        return o[arrs.value] === unwrappedValue[level];
      }, {
        childrenKeyName: arrs.children
      }); // debugger

      var label = selectedOptions.length ? selectedOptions.map(function (o) {
        return o[arrs.label];
      }) : value;
      return displayRender(label, selectedOptions);
    }

    return null;
  };

  var rcCascaderPopupClassName = classNames(_defineProperty({}, "".concat(prefixCls, "-menu-empty"), options.length === 1 && options[0].value === 'NOT_FOUND')); // 输入框后面的图标

  var arrowCls = classNames((_classNames3 = {}, _defineProperty(_classNames3, "".concat(prefixCls, "-picker-arrow"), true), _defineProperty(_classNames3, "".concat(prefixCls, "-picker-arrow-expand"), popupVisible), _classNames3));
  var pickerLabelCls = classNames("".concat(prefixCls, "-picker-label"), _defineProperty({}, "".concat(prefixCls, "-picker-").concat(endSize), endSize)); // 获取到输入框中的icon

  var getInputIcon = function getInputIcon() {
    return suffixIcon ? replaceElement(suffixIcon, /*#__PURE__*/React.createElement("span", {
      className: "".concat(prefixCls, "-picker-arrow")
    }, suffixIcon), function () {
      var _classNames5;

      return {
        className: classNames((_classNames5 = {}, _defineProperty(_classNames5, suffixIcon.props.className, suffixIcon.props.className), _defineProperty(_classNames5, "".concat(prefixCls, "-picker-arrow"), true), _classNames5))
      };
    }) : /*#__PURE__*/React.createElement(DownLine, {
      className: arrowCls
    });
  };

  var renderElement = props.children || /*#__PURE__*/React.createElement("span", {
    className: pickerCls,
    style: style,
    title: showPickerTitle ? pickerTitle || getLabel() : undefined
  }, (value === null || value === void 0 ? void 0 : value.length) > 0 ? /*#__PURE__*/React.createElement("span", {
    className: pickerLabelCls
  }, getLabel()) : null, /*#__PURE__*/React.createElement(Input, {
    ref: inputRef,
    tabIndex: -1,
    placeholder: value && value.length > 0 ? undefined : placeholder,
    className: "".concat(prefixCls, "-input"),
    disabled: disabled,
    value: inputValue,
    readOnly: isReadOnly(showSearch, readOnly),
    onChange: !isReadOnly(showSearch, readOnly) ? handleInputChange : undefined,
    onClick: !isReadOnly(showSearch, readOnly) ? handleInputClick : undefined,
    onKeyDown: handleKeyDown,
    onBlur: !isReadOnly(showSearch, readOnly) ? handleInputBlur : undefined,
    size: endSize
  }), renderClearIcon, getInputIcon());
  /** ------ 级联多选 ------ */

  var onItemRemove = function onItemRemove(curVal) {
    var result = value.filter(function (keys) {
      return keys.join('/') !== curVal;
    });
    setValue(result);
  };

  var renderMutipleSelect = function renderMutipleSelect() {
    var fields = getFilledFieldNames(props);

    var _getSelectOpts = getSelectOpts(fields, value, props.options),
        _getSelectOpts2 = _slicedToArray(_getSelectOpts, 2),
        selectOpts = _getSelectOpts2[0],
        selectVals = _getSelectOpts2[1];

    var selectProps = {
      placeholder: '请选择' || placeholder,
      mode: 'multiple',
      dropdownRender: function dropdownRender(menu) {
        return null;
      },
      dropdownStyle: {
        padding: 0
      },
      value: selectVals,
      onDeselect: onItemRemove,
      tagRender: tagRender,
      maxTagCount: maxTagCount,
      maxTagTextLength: maxTagTextLength,
      showSearch: false,
      showArrow: true,
      suffixIcon: suffixIcon
    };

    if (typeof collapse === 'boolean') {
      selectProps.maxTagCount = maxTagCount;
    } else {
      selectProps.maxTagCount = collapse;
    }

    return /*#__PURE__*/React.createElement(Select, Object.assign({}, selectProps, {
      style: style,
      className: className
    }), selectOpts.map(function (item) {
      return /*#__PURE__*/React.createElement(Select.Option, {
        key: item.value,
        value: item.value
      }, item.label);
    }));
  };

  var onTreeCheck = function onTreeCheck(keys, info) {
    setValue(info.checkedChildrenKeys, []); // mutipleTreeValsRef.current = keys as CascaderValueType[];
  };

  var onTreeSelect = function onTreeSelect(keys, info, checkedKeys) {
    // 如果是多选 + 数据按需加载的情况下
    if (multiple && loadData) {
      setValue(checkedKeys, []);
    }
  };

  var defaultDropdownRender = function defaultDropdownRender(menus) {
    var _options;

    return /*#__PURE__*/React.createElement(React.Fragment, null, multiple && ((_options = options) === null || _options === void 0 ? void 0 : _options.filter(function (item) {
      return !item.isEmptyNode;
    }).length) ? /*#__PURE__*/React.createElement(MutipleDropdown, {
      treeData: options,
      onCheck: onTreeCheck,
      onSelect: onTreeSelect,
      checkedKeys: value,
      loadData: loadData,
      columnWidth: dropdownMenuColumnWidth,
      columnStyle: dropdownMenuColumnStyle,
      fieldNames: getFilledFieldNames(props)
    }) : menus, dropdownFooterContent && /*#__PURE__*/React.createElement("div", {
      className: "".concat(prefixCls, "-footer")
    }, dropdownFooterContent));
  };
  /** ------ 级联多选 ------ */


  var loadingIcon = /*#__PURE__*/React.createElement("span", {
    className: "".concat(prefixCls, "-menu-item-loading-icon")
  }, /*#__PURE__*/React.createElement("img", {
    src: loadingGif,
    style: {
      width: 16,
      marginTop: 3
    },
    alt: "\u52A0\u8F7D\u4E2D\u3002\u3002\u3002\u3002"
  })); // fetch options by scroll infinite

  var handleScroll = useCallback(scrollInfiniteFun(infiniteHasMore, scrollInfinite, onPopupScroll), [infiniteHasMore, scrollInfinite, onPopupScroll]);
  return /*#__PURE__*/React.createElement(RcCascader, Object.assign({}, restProps, {
    getPopupContainer: getPopupContainer || getCtxPopupContainer,
    prefixCls: prefixCls,
    options: options,
    value: value,
    dropdownMenuColumnStyle: _objectSpread({
      width: dropdownMenuColumnWidth
    }, dropdownMenuColumnStyle),
    popupClassName: rcCascaderPopupClassName,
    popupVisible: selectVisible,
    onPopupVisibleChange: handlePopupVisibleChange,
    onChange: handleChange,
    expandIcon: /*#__PURE__*/React.createElement(RightLine, null),
    loadingIcon: loadingIcon,
    disabled: disabled,
    dropdownRender: dropdownRender || defaultDropdownRender,
    onPopupScroll: handleScroll,
    loadData: loadData
  }), !multiple ? renderElement : renderMutipleSelect());
};

Cascader.defaultProps = {
  // size: 'medium',
  disabled: false,
  allowClear: true,
  infiniteHasMore: true
};
export default Cascader;