import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import { resolveDirective as _resolveDirective, createVNode as _createVNode } from "vue";
import { useInjectTreeSelectContext } from './Context';
import { computed, defineComponent, nextTick, ref, watch } from 'vue';
import { optionListProps } from './props';
import useMemo from '../_util/hooks/useMemo';
import KeyCode from '../_util/KeyCode';
import Tree from '../vc-tree/Tree';
var HIDDEN_STYLE = {
  width: 0,
  height: 0,
  display: 'flex',
  overflow: 'hidden',
  opacity: 0,
  border: 0,
  padding: 0,
  margin: 0
};
export default defineComponent({
  name: 'OptionList',
  inheritAttrs: false,
  props: optionListProps(),
  slots: ['notFoundContent', 'menuItemSelectedIcon'],
  setup: function setup(props, _ref) {
    var slots = _ref.slots,
        expose = _ref.expose;
    var context = useInjectTreeSelectContext();
    var treeRef = ref();
    var memoOptions = useMemo(function () {
      return props.options;
    }, [function () {
      return props.open;
    }, function () {
      return props.options;
    }], function (next, prev) {
      return next[0] && prev[1] !== next[1];
    });
    var valueKeys = computed(function () {
      var _context$value = context.value,
          checkedKeys = _context$value.checkedKeys,
          getEntityByValue = _context$value.getEntityByValue;
      return checkedKeys.map(function (val) {
        var entity = getEntityByValue(val);
        return entity ? entity.key : null;
      });
    });
    var mergedCheckedKeys = computed(function () {
      var _context$value2 = context.value,
          checkable = _context$value2.checkable,
          halfCheckedKeys = _context$value2.halfCheckedKeys;

      if (!checkable) {
        return null;
      }

      return {
        checked: valueKeys.value,
        halfChecked: halfCheckedKeys
      };
    });
    watch(function () {
      return props.open;
    }, function () {
      nextTick(function () {
        if (props.open && !props.multiple && valueKeys.value.length) {
          var _treeRef$value;

          (_treeRef$value = treeRef.value) === null || _treeRef$value === void 0 ? void 0 : _treeRef$value.scrollTo({
            key: valueKeys.value[0]
          });
        }
      });
    }, {
      immediate: true,
      flush: 'post'
    }); // ========================== Search ==========================

    var lowerSearchValue = computed(function () {
      return String(props.searchValue).toLowerCase();
    });

    var filterTreeNode = function filterTreeNode(treeNode) {
      if (!lowerSearchValue.value) {
        return false;
      }

      return String(treeNode[context.value.treeNodeFilterProp]).toLowerCase().includes(lowerSearchValue.value);
    }; // =========================== Keys ===========================


    var expandedKeys = ref(context.value.treeDefaultExpandedKeys);
    var searchExpandedKeys = ref(null);
    watch(function () {
      return props.searchValue;
    }, function () {
      if (props.searchValue) {
        searchExpandedKeys.value = props.flattenOptions.map(function (o) {
          return o.key;
        });
      }
    }, {
      immediate: true
    });
    var mergedExpandedKeys = computed(function () {
      if (context.value.treeExpandedKeys) {
        return _toConsumableArray(context.value.treeExpandedKeys);
      }

      return props.searchValue ? searchExpandedKeys.value : expandedKeys.value;
    });

    var onInternalExpand = function onInternalExpand(keys) {
      var _context$value$onTree, _context$value3;

      expandedKeys.value = keys;
      searchExpandedKeys.value = keys;
      (_context$value$onTree = (_context$value3 = context.value).onTreeExpand) === null || _context$value$onTree === void 0 ? void 0 : _context$value$onTree.call(_context$value3, keys);
    }; // ========================== Events ==========================


    var onListMouseDown = function onListMouseDown(event) {
      event.preventDefault();
    };

    var onInternalSelect = function onInternalSelect(_, _ref2) {
      var key = _ref2.node.key;
      var _context$value4 = context.value,
          getEntityByKey = _context$value4.getEntityByKey,
          checkable = _context$value4.checkable,
          checkedKeys = _context$value4.checkedKeys;
      var entity = getEntityByKey(key, checkable ? 'checkbox' : 'select');

      if (entity !== null) {
        var _props$onSelect;

        (_props$onSelect = props.onSelect) === null || _props$onSelect === void 0 ? void 0 : _props$onSelect.call(props, entity.data.value, {
          selected: !checkedKeys.includes(entity.data.value)
        });
      }

      if (!props.multiple) {
        var _props$onToggleOpen;

        (_props$onToggleOpen = props.onToggleOpen) === null || _props$onToggleOpen === void 0 ? void 0 : _props$onToggleOpen.call(props, false);
      }
    }; // ========================= Keyboard =========================


    var activeKey = ref(null);
    var activeEntity = computed(function () {
      return context.value.getEntityByKey(activeKey.value);
    });

    var setActiveKey = function setActiveKey(key) {
      activeKey.value = key;
    };

    expose({
      scrollTo: function scrollTo() {
        var _treeRef$value2, _treeRef$value2$scrol;

        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }

        return (_treeRef$value2 = treeRef.value) === null || _treeRef$value2 === void 0 ? void 0 : (_treeRef$value2$scrol = _treeRef$value2.scrollTo) === null || _treeRef$value2$scrol === void 0 ? void 0 : _treeRef$value2$scrol.call.apply(_treeRef$value2$scrol, [_treeRef$value2].concat(args));
      },
      onKeydown: function onKeydown(event) {
        var _treeRef$value3;

        var which = event.which;

        switch (which) {
          // >>> Arrow keys
          case KeyCode.UP:
          case KeyCode.DOWN:
          case KeyCode.LEFT:
          case KeyCode.RIGHT:
            (_treeRef$value3 = treeRef.value) === null || _treeRef$value3 === void 0 ? void 0 : _treeRef$value3.onKeydown(event);
            break;
          // >>> Select item

          case KeyCode.ENTER:
            {
              var _activeEntity$value;

              var _ref3 = ((_activeEntity$value = activeEntity.value) === null || _activeEntity$value === void 0 ? void 0 : _activeEntity$value.data.node) || {},
                  selectable = _ref3.selectable,
                  value = _ref3.value;

              if (selectable !== false) {
                onInternalSelect(null, {
                  node: {
                    key: activeKey.value
                  },
                  selected: !context.value.checkedKeys.includes(value)
                });
              }

              break;
            }
          // >>> Close

          case KeyCode.ESC:
            {
              props.onToggleOpen(false);
            }
        }
      },
      onKeyup: function onKeyup() {}
    });
    return function () {
      var _slots$notFoundConten;

      var prefixCls = props.prefixCls,
          height = props.height,
          itemHeight = props.itemHeight,
          virtual = props.virtual,
          multiple = props.multiple,
          searchValue = props.searchValue,
          open = props.open,
          _props$notFoundConten = props.notFoundContent,
          notFoundContent = _props$notFoundConten === void 0 ? (_slots$notFoundConten = slots.notFoundContent) === null || _slots$notFoundConten === void 0 ? void 0 : _slots$notFoundConten.call(slots) : _props$notFoundConten,
          onMouseenter = props.onMouseenter;
      var _context$value5 = context.value,
          checkable = _context$value5.checkable,
          treeDefaultExpandAll = _context$value5.treeDefaultExpandAll,
          treeIcon = _context$value5.treeIcon,
          showTreeIcon = _context$value5.showTreeIcon,
          switcherIcon = _context$value5.switcherIcon,
          treeLine = _context$value5.treeLine,
          loadData = _context$value5.loadData,
          treeLoadedKeys = _context$value5.treeLoadedKeys,
          treeMotion = _context$value5.treeMotion,
          onTreeLoad = _context$value5.onTreeLoad; // ========================== Render ==========================

      if (memoOptions.value.length === 0) {
        return _createVNode("div", {
          "role": "listbox",
          "class": "".concat(prefixCls, "-empty"),
          "onMousedown": onListMouseDown
        }, [notFoundContent]);
      }

      var treeProps = {};

      if (treeLoadedKeys) {
        treeProps.loadedKeys = treeLoadedKeys;
      }

      if (mergedExpandedKeys.value) {
        treeProps.expandedKeys = mergedExpandedKeys.value;
      }

      return _createVNode("div", {
        "onMousedown": onListMouseDown,
        "onMouseenter": onMouseenter
      }, [activeEntity.value && open && _createVNode("span", {
        "style": HIDDEN_STYLE,
        "aria-live": "assertive"
      }, [activeEntity.value.data.value]), _createVNode(Tree, _objectSpread(_objectSpread({
        "ref": treeRef,
        "focusable": false,
        "prefixCls": "".concat(prefixCls, "-tree"),
        "treeData": memoOptions.value,
        "height": height,
        "itemHeight": itemHeight,
        "virtual": virtual,
        "multiple": multiple,
        "icon": treeIcon,
        "showIcon": showTreeIcon,
        "switcherIcon": switcherIcon,
        "showLine": treeLine,
        "loadData": searchValue ? null : loadData,
        "motion": treeMotion,
        "checkable": checkable,
        "checkStrictly": true,
        "checkedKeys": mergedCheckedKeys.value,
        "selectedKeys": !checkable ? valueKeys.value : [],
        "defaultExpandAll": treeDefaultExpandAll
      }, treeProps), {}, {
        "onActiveChange": setActiveKey,
        "onSelect": onInternalSelect,
        "onCheck": onInternalSelect,
        "onExpand": onInternalExpand,
        "onLoad": onTreeLoad,
        "filterTreeNode": filterTreeNode
      }), _objectSpread(_objectSpread({}, slots), {}, {
        checkable: context.value.customCheckable
      }))]);
    };
  }
});