'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var vue = require('vue');
require('../../../utils/index.cjs');
require('../../../hooks/index.cjs');
var BaseSelect = require('../../vc-select/src/BaseSelect.cjs');
var useId = require('../../vc-select/src/hooks/useId.cjs');
var conductUtil = require('../../vc-tree/src/utils/conductUtil.cjs');
var useMaxLevel = require('../../vc-tree/src/useMaxLevel.cjs');
var commonUtil = require('./utils/commonUtil.cjs');
var useEntities = require('./hooks/useEntities.cjs');
var useSearchConfig = require('./hooks/useSearchConfig.cjs');
var useSearchOptions = require('./hooks/useSearchOptions.cjs');
var useMissingValues = require('./hooks/useMissingValues.cjs');
var treeUtil = require('./utils/treeUtil.cjs');
var useDisplayValues = require('./hooks/useDisplayValues.cjs');
var context = require('./context.cjs');
var index$1 = require('./OptionList/index.cjs');
var omit = require('../../../utils/lang/omit.cjs');
var propType = require('../../../utils/vue/propType.cjs');
var vueTypes = require('../../../utils/vue/vueTypes.cjs');
var initDefaultProps = require('../../../utils/vue/initDefaultProps.cjs');
var index = require('../../../hooks/use-merged-state/index.cjs');
var log = require('../../../utils/log.cjs');

function baseCascaderProps() {
  return {
    ...omit.omit(BaseSelect.baseSelectPropsWithoutPrivate(), ["tokenSeparators", "mode", "showSearch"]),
    // MISC
    id: String,
    prefixCls: String,
    fieldNames: propType.objectType(),
    children: Array,
    // Value
    value: {
      type: [String, Number, Array]
    },
    defaultValue: {
      type: [String, Number, Array]
    },
    changeOnSelect: {
      type: Boolean,
      default: void 0
    },
    displayRender: Function,
    checkable: {
      type: Boolean,
      default: void 0
    },
    showCheckedStrategy: {
      type: String,
      default: commonUtil.SHOW_PARENT
    },
    // Search
    showSearch: {
      type: [Boolean, Object],
      default: void 0
    },
    searchValue: String,
    onSearch: Function,
    // Trigger
    expandTrigger: String,
    // Options
    options: Array,
    /** @private Internal usage. Do not use in your production. */
    dropdownPrefixCls: String,
    loadData: Function,
    // Open
    /** @deprecated Use `open` instead */
    popupVisible: {
      type: Boolean,
      default: void 0
    },
    /** @deprecated Use `dropdownClassName` instead */
    popupClassName: String,
    dropdownClassName: String,
    dropdownMenuColumnStyle: {
      type: Object,
      default: void 0
    },
    /** @deprecated Use `dropdownStyle` instead */
    popupStyle: {
      type: Object,
      default: void 0
    },
    dropdownStyle: {
      type: Object,
      default: void 0
    },
    /** @deprecated Use `placement` instead */
    popupPlacement: String,
    placement: String,
    /** @deprecated Use `onDropdownVisibleChange` instead */
    onPopupVisibleChange: Function,
    onDropdownVisibleChange: Function,
    // Icon
    expandIcon: vueTypes.default.any,
    loadingIcon: vueTypes.default.any
  };
}
function singleCascaderProps() {
  return {
    ...baseCascaderProps(),
    checkable: Boolean,
    onChange: Function
  };
}
function multipleCascaderProps() {
  return {
    ...baseCascaderProps(),
    checkable: Boolean,
    onChange: Function
  };
}
function internalCascaderProps() {
  return {
    ...baseCascaderProps(),
    onChange: Function,
    customSlots: Object
  };
}
function isMultipleValue(value) {
  return Array.isArray(value) && Array.isArray(value[0]);
}
function toRawValues(value) {
  if (!value)
    return [];
  if (isMultipleValue(value))
    return value;
  return (value.length === 0 ? [] : [value]).map((val) => Array.isArray(val) ? val : [val]);
}
var VcCascader = /* @__PURE__ */ vue.defineComponent({
  compatConfig: {
    MODE: 3
  },
  name: "Cascader",
  inheritAttrs: false,
  props: initDefaultProps.initDefaultProps(internalCascaderProps(), {}),
  setup(props, {
    attrs,
    expose,
    slots
  }) {
    const mergedId = useId.default(vue.toRef(props, "id"));
    const multiple = vue.computed(() => !!props.checkable);
    const [rawValues, setRawValues] = index.useMergedState(props.defaultValue, {
      value: vue.computed(() => props.value),
      postState: toRawValues
    });
    const mergedFieldNames = vue.computed(() => commonUtil.fillFieldNames(props.fieldNames));
    const mergedOptions = vue.computed(() => props.options || []);
    const pathKeyEntities = useEntities.default(mergedOptions, mergedFieldNames);
    const getValueByKeyPath = (pathKeys) => {
      const keyPathEntities = pathKeyEntities.value;
      return pathKeys.map((pathKey) => {
        const {
          nodes
        } = keyPathEntities[pathKey];
        return nodes.map((node) => node[mergedFieldNames.value.value]);
      });
    };
    const [mergedSearchValue, setSearchValue] = index.useMergedState("", {
      value: vue.computed(() => props.searchValue),
      postState: (search) => search || ""
    });
    const onInternalSearch = (searchText, info) => {
      setSearchValue(searchText);
      if (info.source !== "blur" && props.onSearch)
        props.onSearch(searchText);
    };
    const {
      showSearch: mergedShowSearch,
      searchConfig: mergedSearchConfig
    } = useSearchConfig.default(vue.toRef(props, "showSearch"));
    const searchOptions = useSearchOptions.default(mergedSearchValue, mergedOptions, mergedFieldNames, vue.computed(() => props.dropdownPrefixCls || props.prefixCls), mergedSearchConfig, vue.toRef(props, "changeOnSelect"));
    const missingValuesInfo = useMissingValues.default(mergedOptions, mergedFieldNames, rawValues);
    const [checkedValues, halfCheckedValues, missingCheckedValues] = [vue.ref([]), vue.ref([]), vue.ref([])];
    const {
      maxLevel,
      levelEntities
    } = useMaxLevel.default(pathKeyEntities);
    vue.watchEffect(() => {
      const [existValues, missingValues] = missingValuesInfo.value;
      if (!multiple.value || !rawValues.value.length) {
        [checkedValues.value, halfCheckedValues.value, missingCheckedValues.value] = [existValues, [], missingValues];
        return;
      }
      const keyPathValues = commonUtil.toPathKeys(existValues);
      const keyPathEntities = pathKeyEntities.value;
      const {
        checkedKeys,
        halfCheckedKeys
      } = conductUtil.conductCheck(keyPathValues, true, keyPathEntities, maxLevel.value, levelEntities.value);
      [checkedValues.value, halfCheckedValues.value, missingCheckedValues.value] = [getValueByKeyPath(checkedKeys), getValueByKeyPath(halfCheckedKeys), missingValues];
    });
    const deDuplicatedValues = vue.computed(() => {
      const checkedKeys = commonUtil.toPathKeys(checkedValues.value);
      const deduplicateKeys = treeUtil.formatStrategyValues(checkedKeys, pathKeyEntities.value, props.showCheckedStrategy);
      return [...missingCheckedValues.value, ...getValueByKeyPath(deduplicateKeys)];
    });
    const displayValues = useDisplayValues.default(deDuplicatedValues, mergedOptions, mergedFieldNames, multiple, vue.toRef(props, "displayRender"));
    const triggerChange = (nextValues) => {
      setRawValues(nextValues);
      if (props.onChange) {
        const nextRawValues = toRawValues(nextValues);
        const valueOptions = nextRawValues.map((valueCells) => treeUtil.toPathOptions(valueCells, mergedOptions.value, mergedFieldNames.value).map((valueOpt) => valueOpt.option));
        const triggerValues = multiple.value ? nextRawValues : nextRawValues[0];
        const triggerOptions = multiple.value ? valueOptions : valueOptions[0];
        props.onChange(triggerValues, triggerOptions);
      }
    };
    const onInternalSelect = (valuePath) => {
      setSearchValue("");
      if (!multiple.value) {
        triggerChange(valuePath);
      } else {
        const pathKey = commonUtil.toPathKey(valuePath);
        const checkedPathKeys = commonUtil.toPathKeys(checkedValues.value);
        const halfCheckedPathKeys = commonUtil.toPathKeys(halfCheckedValues.value);
        const existInChecked = checkedPathKeys.includes(pathKey);
        const existInMissing = missingCheckedValues.value.some((valueCells) => commonUtil.toPathKey(valueCells) === pathKey);
        let nextCheckedValues = checkedValues.value;
        let nextMissingValues = missingCheckedValues.value;
        if (existInMissing && !existInChecked) {
          nextMissingValues = missingCheckedValues.value.filter((valueCells) => commonUtil.toPathKey(valueCells) !== pathKey);
        } else {
          const nextRawCheckedKeys = existInChecked ? checkedPathKeys.filter((key) => key !== pathKey) : [...checkedPathKeys, pathKey];
          let checkedKeys;
          if (existInChecked) {
            ({
              checkedKeys
            } = conductUtil.conductCheck(nextRawCheckedKeys, {
              checked: false,
              halfCheckedKeys: halfCheckedPathKeys
            }, pathKeyEntities.value, maxLevel.value, levelEntities.value));
          } else {
            ({
              checkedKeys
            } = conductUtil.conductCheck(nextRawCheckedKeys, true, pathKeyEntities.value, maxLevel.value, levelEntities.value));
          }
          const deDuplicatedKeys = treeUtil.formatStrategyValues(checkedKeys, pathKeyEntities.value, props.showCheckedStrategy);
          nextCheckedValues = getValueByKeyPath(deDuplicatedKeys);
        }
        triggerChange([...nextMissingValues, ...nextCheckedValues]);
      }
    };
    const onDisplayValuesChange = (_, info) => {
      if (info.type === "clear") {
        triggerChange([]);
        return;
      }
      const {
        valueCells
      } = info.values[0];
      onInternalSelect(valueCells);
    };
    if (process.env.NODE_ENV !== "production") {
      vue.watchEffect(() => {
        log.devWarning(!props.onPopupVisibleChange, "Cascader", "`popupVisibleChange` is deprecated. Please use `dropdownVisibleChange` instead.");
        log.devWarning(props.popupVisible === void 0, "Cascader", "`popupVisible` is deprecated. Please use `open` instead.");
        log.devWarning(props.popupClassName === void 0, "Cascader", "`popupClassName` is deprecated. Please use `dropdownClassName` instead.");
        log.devWarning(props.popupPlacement === void 0, "Cascader", "`popupPlacement` is deprecated. Please use `placement` instead.");
        log.devWarning(props.popupStyle === void 0, "Cascader", "`popupStyle` is deprecated. Please use `dropdownStyle` instead.");
      });
    }
    const mergedOpen = vue.computed(() => props.open !== void 0 ? props.open : props.popupVisible);
    const mergedDropdownClassName = vue.computed(() => props.dropdownClassName || props.popupClassName);
    const mergedDropdownStyle = vue.computed(() => props.dropdownStyle || props.popupStyle || {});
    const mergedPlacement = vue.computed(() => props.placement || props.popupPlacement);
    const onInternalDropdownVisibleChange = (nextVisible) => {
      var _a, _b;
      (_a = props.onDropdownVisibleChange) == null ? void 0 : _a.call(props, nextVisible);
      (_b = props.onPopupVisibleChange) == null ? void 0 : _b.call(props, nextVisible);
    };
    const {
      changeOnSelect,
      checkable,
      dropdownPrefixCls,
      loadData,
      expandTrigger,
      expandIcon,
      loadingIcon,
      dropdownMenuColumnStyle,
      customSlots
    } = vue.toRefs(props);
    context.useProvideCascader({
      options: mergedOptions,
      fieldNames: mergedFieldNames,
      values: checkedValues,
      halfValues: halfCheckedValues,
      changeOnSelect,
      onSelect: onInternalSelect,
      checkable,
      searchOptions,
      dropdownPrefixCls,
      loadData,
      expandTrigger,
      expandIcon,
      loadingIcon,
      dropdownMenuColumnStyle,
      customSlots
    });
    const selectRef = vue.ref();
    expose({
      focus() {
        var _a;
        (_a = selectRef.value) == null ? void 0 : _a.focus();
      },
      blur() {
        var _a;
        (_a = selectRef.value) == null ? void 0 : _a.blur();
      },
      scrollTo(arg) {
        var _a;
        (_a = selectRef.value) == null ? void 0 : _a.scrollTo(arg);
      }
    });
    const pickProps = vue.computed(() => {
      return omit.omit(props, [
        "id",
        "prefixCls",
        "fieldNames",
        // Value
        "defaultValue",
        "value",
        "changeOnSelect",
        "onChange",
        "displayRender",
        "checkable",
        // Search
        "searchValue",
        "onSearch",
        "showSearch",
        // Trigger
        "expandTrigger",
        // Options
        "options",
        "dropdownPrefixCls",
        "loadData",
        // Open
        "popupVisible",
        "open",
        "popupClassName",
        "dropdownClassName",
        "dropdownMenuColumnStyle",
        "popupPlacement",
        "placement",
        "onDropdownVisibleChange",
        "onPopupVisibleChange",
        // Icon
        "expandIcon",
        "loadingIcon",
        "customSlots",
        "showCheckedStrategy",
        // Children
        "children"
      ]);
    });
    return () => {
      const emptyOptions = !(mergedSearchValue.value ? searchOptions.value : mergedOptions.value).length;
      const {
        dropdownMatchSelectWidth = false
      } = props;
      const dropdownStyle = mergedSearchValue.value && mergedSearchConfig.value.matchInputWidth || emptyOptions ? {} : {
        minWidth: "auto"
      };
      return vue.createVNode(BaseSelect.default, {
        ...pickProps.value,
        ...attrs,
        "ref": selectRef,
        "id": mergedId,
        "prefixCls": props.prefixCls,
        "dropdownMatchSelectWidth": dropdownMatchSelectWidth,
        "dropdownStyle": {
          ...mergedDropdownStyle.value,
          ...dropdownStyle
        },
        "displayValues": displayValues.value,
        "onDisplayValuesChange": onDisplayValuesChange,
        "mode": multiple.value ? "multiple" : void 0,
        "searchValue": mergedSearchValue.value,
        "onSearch": onInternalSearch,
        "showSearch": mergedShowSearch.value,
        "OptionList": index$1.default,
        "emptyOptions": emptyOptions,
        "open": mergedOpen.value,
        "dropdownClassName": mergedDropdownClassName.value,
        "placement": mergedPlacement.value,
        "onDropdownVisibleChange": onInternalDropdownVisibleChange,
        "getRawInputElement": () => {
          var _a;
          return (_a = slots.default) == null ? void 0 : _a.call(slots);
        }
      }, slots);
    };
  }
});

exports.SHOW_CHILD = commonUtil.SHOW_CHILD;
exports.SHOW_PARENT = commonUtil.SHOW_PARENT;
exports.default = VcCascader;
exports.internalCascaderProps = internalCascaderProps;
exports.multipleCascaderProps = multipleCascaderProps;
exports.singleCascaderProps = singleCascaderProps;
//# sourceMappingURL=Cascader.cjs.map
