"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
exports.panelProps = panelProps;
var _vue = require("vue");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _Cascader = require("./Cascader");
var _type = require("../_util/type");
var _vueTypes = _interopRequireDefault(require("../_util/vue-types"));
var _propsUtil = require("../_util/props-util");
var _useMergedState = _interopRequireDefault(require("../_util/hooks/useMergedState"));
var _commonUtil = require("./utils/commonUtil");
var _useEntities = _interopRequireDefault(require("./hooks/useEntities"));
var _useMissingValues = _interopRequireDefault(require("./hooks/useMissingValues"));
var _useMaxLevel = _interopRequireDefault(require("../vc-tree/useMaxLevel"));
var _conductUtil = require("../vc-tree/utils/conductUtil");
var _treeUtil = require("./utils/treeUtil");
var _context = require("./context");
var _OptionList = _interopRequireDefault(require("./OptionList"));
var _useBaseProps = require("../vc-select/hooks/useBaseProps");
var _toReactive = require("../_util/toReactive");
function panelProps() {
  return {
    // Value
    value: {
      type: [String, Number, Array]
    },
    defaultValue: {
      type: [String, Number, Array]
    },
    changeOnSelect: {
      type: Boolean,
      default: undefined
    },
    onChange: Function,
    prefixCls: String,
    checkable: {
      type: Boolean,
      default: undefined
    },
    fieldNames: (0, _type.objectType)(),
    showCheckedStrategy: {
      type: String,
      default: _Cascader.SHOW_PARENT
    },
    // Options
    options: Array,
    loadData: Function,
    // Trigger
    expandTrigger: String,
    // Icon
    expandIcon: _vueTypes.default.any,
    loadingIcon: _vueTypes.default.any,
    direction: (0, _type.stringType)(),
    notFoundContent: _vueTypes.default.any,
    disabled: (0, _type.booleanType)(false),
    /** @private Internal usage. Do not use in your production. */
    dropdownPrefixCls: String,
    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]);
}
function noop() {}
var _default = exports.default = (0, _vue.defineComponent)({
  name: 'VcCascaderPanel',
  inheritAttrs: false,
  props: (0, _propsUtil.initDefaultProps)(panelProps(), {
    notFoundContent: 'Not Found'
  }),
  setup(props, {
    attrs
  }) {
    const multiple = (0, _vue.computed)(() => props.checkable);
    // =========================== Values ===========================
    const [rawValues, setRawValues] = (0, _useMergedState.default)(props.defaultValue, {
      value: (0, _vue.computed)(() => props.value),
      postState: toRawValues
    });
    // ========================= FieldNames =========================
    const mergedFieldNames = (0, _vue.computed)(() => (0, _commonUtil.fillFieldNames)(props.fieldNames));
    // =========================== Option ===========================
    const mergedOptions = (0, _vue.computed)(() => props.options || []);
    // Only used in multiple mode, this fn will not call in single mode
    const pathKeyEntities = (0, _useEntities.default)(mergedOptions, mergedFieldNames);
    /** Convert path key back to value format */
    const getValueByKeyPath = pathKeys => {
      const keyPathEntities = pathKeyEntities.value;
      return pathKeys.map(pathKey => {
        const {
          nodes
        } = keyPathEntities[pathKey];
        return nodes.map(node => node[mergedFieldNames.value.value]);
      });
    };
    // =========================== Values ===========================
    const missingValuesInfo = (0, _useMissingValues.default)(mergedOptions, mergedFieldNames, rawValues);
    // Fill `rawValues` with checked conduction values
    const [checkedValues, halfCheckedValues, missingCheckedValues] = [(0, _vue.ref)([]), (0, _vue.ref)([]), (0, _vue.ref)([])];
    const {
      maxLevel,
      levelEntities
    } = (0, _useMaxLevel.default)(pathKeyEntities);
    (0, _vue.watchEffect)(() => {
      const [existValues, missingValues] = missingValuesInfo.value;
      if (!multiple.value || !rawValues.value.length) {
        [checkedValues.value, halfCheckedValues.value, missingCheckedValues.value] = [existValues, [], missingValues];
        return;
      }
      const keyPathValues = (0, _commonUtil.toPathKeys)(existValues);
      const keyPathEntities = pathKeyEntities.value;
      const {
        checkedKeys,
        halfCheckedKeys
      } = (0, _conductUtil.conductCheck)(keyPathValues, true, keyPathEntities, maxLevel.value, levelEntities.value);
      // Convert key back to value cells
      [checkedValues.value, halfCheckedValues.value, missingCheckedValues.value] = [getValueByKeyPath(checkedKeys), getValueByKeyPath(halfCheckedKeys), missingValues];
    });
    // =========================== Change ===========================
    const triggerChange = nextValues => {
      setRawValues(nextValues);
      // Save perf if no need trigger event
      if (props.onChange) {
        const nextRawValues = toRawValues(nextValues);
        const valueOptions = nextRawValues.map(valueCells => (0, _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);
      }
    };
    // =========================== Select ===========================
    const onInternalSelect = valuePath => {
      if (!multiple.value) {
        triggerChange(valuePath);
      } else {
        // Prepare conduct required info
        const pathKey = (0, _commonUtil.toPathKey)(valuePath);
        const checkedPathKeys = (0, _commonUtil.toPathKeys)(checkedValues.value);
        const halfCheckedPathKeys = (0, _commonUtil.toPathKeys)(halfCheckedValues.value);
        const existInChecked = checkedPathKeys.includes(pathKey);
        const existInMissing = missingCheckedValues.value.some(valueCells => (0, _commonUtil.toPathKey)(valueCells) === pathKey);
        // Do update
        let nextCheckedValues = checkedValues.value;
        let nextMissingValues = missingCheckedValues.value;
        if (existInMissing && !existInChecked) {
          // Missing value only do filter
          nextMissingValues = missingCheckedValues.value.filter(valueCells => (0, _commonUtil.toPathKey)(valueCells) !== pathKey);
        } else {
          // Update checked key first
          const nextRawCheckedKeys = existInChecked ? checkedPathKeys.filter(key => key !== pathKey) : [...checkedPathKeys, pathKey];
          // Conduction by selected or not
          let checkedKeys;
          if (existInChecked) {
            ({
              checkedKeys
            } = (0, _conductUtil.conductCheck)(nextRawCheckedKeys, {
              checked: false,
              halfCheckedKeys: halfCheckedPathKeys
            }, pathKeyEntities.value, maxLevel.value, levelEntities.value));
          } else {
            ({
              checkedKeys
            } = (0, _conductUtil.conductCheck)(nextRawCheckedKeys, true, pathKeyEntities.value, maxLevel.value, levelEntities.value));
          }
          // console.log(checkedKeys, pathKeyEntities.value, props.showCheckedStrategy);
          // Roll up to parent level keys
          const deDuplicatedKeys = (0, _treeUtil.formatStrategyValues)(checkedKeys, pathKeyEntities.value, props.showCheckedStrategy);
          nextCheckedValues = getValueByKeyPath(deDuplicatedKeys);
        }
        triggerChange([...nextMissingValues, ...nextCheckedValues]);
      }
    };
    // =========================== Context ===========================
    const {
      changeOnSelect,
      checkable,
      loadData,
      expandTrigger,
      expandIcon,
      loadingIcon,
      dropdownPrefixCls,
      customSlots
    } = (0, _vue.toRefs)(props);
    (0, _context.useProvideCascader)({
      options: mergedOptions,
      fieldNames: mergedFieldNames,
      values: checkedValues,
      halfValues: halfCheckedValues,
      changeOnSelect,
      onSelect: onInternalSelect,
      checkable,
      searchOptions: (0, _vue.ref)([]),
      dropdownPrefixCls,
      loadData,
      expandTrigger,
      expandIcon,
      loadingIcon,
      dropdownMenuColumnStyle: (0, _vue.ref)(undefined),
      customSlots
    });
    (0, _useBaseProps.useProvideBaseSelectProps)((0, _toReactive.toReactive)((0, _extends2.default)((0, _extends2.default)({}, (0, _vue.toRefs)(props)), {
      searchValue: '',
      open: true,
      showSearch: false,
      multiple,
      toggleOpen: noop
    })));
    return () => {
      const {
        prefixCls,
        notFoundContent
      } = props;
      const panelPrefixCls = `${prefixCls}-panel`;
      const isEmpty = !mergedOptions.value.length;
      return (0, _vue.createVNode)("div", {
        "class": [panelPrefixCls, {
          [`${panelPrefixCls}-rtl`]: props.direction === 'rtl',
          [`${panelPrefixCls}-empty`]: isEmpty
        }, attrs.class],
        "style": attrs.style
      }, [isEmpty ? notFoundContent : (0, _vue.createVNode)(_OptionList.default, null, null)]);
    };
  }
});