import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import React from 'react';
import TreeNodeItem from './treeNode';
import { onTreeNodeCheck, onTreeNodeSelect, getNodeKeys, getExportCheckedKeys } from './utils/treeFunctions';
import { traverseTreeNode } from './utils/traverseUtils';
import { getNodeIsLeaf, calcEndCheckedKeys, getTrulyKey, getCheckedNodes, __DEFAULT_FIELDNAMES__ } from './utils/_utils';

function getNextLevelArray(treeNodesLevelArray, expandedNode) {
  var nextLevel = expandedNode.level + 1; // 往下找children，展开当前节点的下一个节点

  if (expandedNode.children) {
    treeNodesLevelArray[nextLevel] = expandedNode.children;
  } else {
    treeNodesLevelArray[nextLevel] = [];
  }

  treeNodesLevelArray[nextLevel + 1] = [];
  return treeNodesLevelArray;
}

function getTreeNodesLevelArray(treeData) {
  var fieldNames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : __DEFAULT_FIELDNAMES__;
  var keyToTreeNodeMapRef = arguments.length > 2 ? arguments[2] : undefined;
  var numberKeysSetRef = arguments.length > 3 ? arguments[3] : undefined;
  var expandedKey = arguments.length > 4 ? arguments[4] : undefined;
  var temp = [];
  var data = traverseTreeNode(treeData, fieldNames, keyToTreeNodeMapRef.current, numberKeysSetRef.current, true);
  temp[0] = data;
  if (!expandedKey) return temp;
  var expandedNode = keyToTreeNodeMapRef.current.get(expandedKey);

  if (expandedNode) {
    var curNode = expandedNode;
    var curLevel = expandedNode.level; // 往下找children，展开当前节点的下一个节点

    if (curNode.children) {
      temp[curLevel + 1] = curNode.children;
    } // 往上找parent，展开当前节点的所有父节点


    while (curNode.parent && curLevel > 0) {
      temp[curLevel] = curNode.parent.children;
      curNode = curNode.parent;
      curLevel -= 1;
    }
  }

  return temp;
}

var HorizontalTreeRenderFunction = function HorizontalTreeRenderFunction(props, ref) {
  var treeData = props.treeData,
      style = props.style,
      className = props.className,
      columnWidth = props.columnWidth,
      showIcon = props.showIcon,
      _props$fieldNames = props.fieldNames,
      fieldNames = _props$fieldNames === void 0 ? __DEFAULT_FIELDNAMES__ : _props$fieldNames,
      _props$checkedKeys = props.checkedKeys,
      outerCheckedKeys = _props$checkedKeys === void 0 ? [[]] : _props$checkedKeys,
      _props$defaultChecked = props.defaultCheckedKeys,
      defaultCheckedKeys = _props$defaultChecked === void 0 ? [[]] : _props$defaultChecked,
      _props$checkable = props.checkable,
      checkable = _props$checkable === void 0 ? true : _props$checkable,
      _props$columnStyle = props.columnStyle,
      columnStyle = _props$columnStyle === void 0 ? {} : _props$columnStyle,
      onSelect = props.onSelect,
      onCheck = props.onCheck,
      loadData = props.loadData,
      prefixCls = props.prefixCls;

  var endFieldNames = _objectSpread(_objectSpread({}, __DEFAULT_FIELDNAMES__), fieldNames); // 每一层保存一个selectedkey


  var _React$useState = React.useState([]),
      _React$useState2 = _slicedToArray(_React$useState, 2),
      selectedKeys = _React$useState2[0],
      setSelectedKeys = _React$useState2[1];

  var _React$useState3 = React.useState(new Set()),
      _React$useState4 = _slicedToArray(_React$useState3, 2),
      halfCheckedKeys = _React$useState4[0],
      setHalfCheckedKeys = _React$useState4[1];

  var _React$useState5 = React.useState(calcEndCheckedKeys(outerCheckedKeys || defaultCheckedKeys)),
      _React$useState6 = _slicedToArray(_React$useState5, 2),
      checkedKeys = _React$useState6[0],
      setCheckedKeys = _React$useState6[1]; // const [expandedKeys, setExpandedKeys] = React.useState<Key[]>(
  //   outerExpandedKeys || defaultExpandedKeys,
  // );


  var _React$useState7 = React.useState(null),
      _React$useState8 = _slicedToArray(_React$useState7, 2),
      curLoadingKey = _React$useState8[0],
      setCurLoadingKey = _React$useState8[1];

  var keyToTreeNodeMapRef = React.useRef(new Map());
  var numberKeysSetRef = React.useRef(new Set()); // 保存每个层级的节点数

  var _React$useState9 = React.useState(treeData ? getTreeNodesLevelArray(treeData, endFieldNames, keyToTreeNodeMapRef, numberKeysSetRef) : []),
      _React$useState10 = _slicedToArray(_React$useState9, 2),
      treeNodesLevelArray = _React$useState10[0],
      setTreeNodesLevelArray = _React$useState10[1]; // 当前操作的key


  var currentKeyRef = React.useRef(); // 保存上一次的treeData

  var prevTreeDataRef = React.useRef(); // 保存上一次的checkedKeys

  var prevCheckedKeysRef = React.useRef(); // 保存当前选中的keys

  var checkedKeysRef = React.useRef(checkedKeys); // tree dom

  var horizontalTreeRef = React.useRef(null);

  if (ref) {
    horizontalTreeRef = ref;
  } // 按需加载时更新数据


  var updateNodesLevelArray = function updateNodesLevelArray(expandeds) {
    var lastKey = expandeds ? expandeds[expandeds.length - 1] : undefined;
    var levelArr = getTreeNodesLevelArray(treeData || [], endFieldNames, keyToTreeNodeMapRef, numberKeysSetRef, lastKey);
    setTreeNodesLevelArray(levelArr);
  };

  var updateKeys = function updateKeys(updateCheckedKeys) {
    var _getNodeKeys = getNodeKeys(updateCheckedKeys, keyToTreeNodeMapRef.current),
        _getNodeKeys2 = _slicedToArray(_getNodeKeys, 2),
        endKeys = _getNodeKeys2[0],
        halfKeys = _getNodeKeys2[1];

    setCheckedKeys(endKeys);
    setHalfCheckedKeys(halfKeys);
    return endKeys;
  };

  if ('treeData' in props && prevTreeDataRef.current !== treeData) {
    updateNodesLevelArray([currentKeyRef.current]);
  }

  if ('checkedKeys' in props && outerCheckedKeys !== prevCheckedKeysRef.current) {
    var endCheckedKeys = calcEndCheckedKeys(outerCheckedKeys); // if (endCheckedKeys.size === 0) {
    //   setCheckedKeys(endCheckedKeys);
    // } else {

    updateKeys(endCheckedKeys); // }
  } // if ('expandedKeys' in props && expandedKeys !== outerExpandedKeys) {
  //   setExpandedKeys(outerExpandedKeys);
  // }


  prevTreeDataRef.current = treeData;
  prevCheckedKeysRef.current = outerCheckedKeys;
  checkedKeysRef.current = checkedKeys;

  var nodeSelect = function nodeSelect(e, treeNode, checkedKeysSelected) {
    var cKeysSelected = [];

    if (checkedKeysSelected) {
      var _getExportCheckedKeys = getExportCheckedKeys(checkedKeysSelected, keyToTreeNodeMapRef.current),
          _getExportCheckedKeys2 = _slicedToArray(_getExportCheckedKeys, 2),
          exportCheckedKeys = _getExportCheckedKeys2[0],
          exportFilterAnCheckedKeys = _getExportCheckedKeys2[1]; // cKeysSelected = [...cKeysSelected].map(
      //   (key) => getTrulyKey(key, numberKeysSetRef.current)[0],
      // );


      cKeysSelected = exportFilterAnCheckedKeys.map(function (key) {
        return getTrulyKey(key, numberKeysSetRef.current)[0];
      });
    }

    var _onTreeNodeSelect = onTreeNodeSelect(treeNode, new Set(_toConsumableArray(selectedKeys)), endFieldNames, keyToTreeNodeMapRef.current, false, numberKeysSetRef.current),
        _onTreeNodeSelect2 = _slicedToArray(_onTreeNodeSelect, 2),
        keys = _onTreeNodeSelect2[0],
        selectedTreeNodes = _onTreeNodeSelect2[1];

    selectedKeys[treeNode.level || 0] = keys[0]; // 清除当前层级后面所有的key

    var newSelectedKeys = selectedKeys.slice(0, treeNode.level + 1);
    setSelectedKeys(newSelectedKeys);

    var _getTrulyKey = getTrulyKey(treeNode.nodeKey, numberKeysSetRef.current),
        _getTrulyKey2 = _slicedToArray(_getTrulyKey, 1),
        exportKeys = _getTrulyKey2[0];

    onSelect === null || onSelect === void 0 ? void 0 : onSelect(exportKeys, {
      event: 'select',
      selected: !treeNode.selected,
      nativeEvent: e.nativeEvent,
      selectedNodes: selectedTreeNodes
    }, cKeysSelected);
  };

  var onNodeCheck = function onNodeCheck(e, treeNode) {
    var newCheckedKeysSet = new Set(_toConsumableArray(checkedKeys));

    var _onTreeNodeCheck = onTreeNodeCheck(treeNode, e.target.checked, newCheckedKeysSet, keyToTreeNodeMapRef.current),
        _onTreeNodeCheck2 = _slicedToArray(_onTreeNodeCheck, 3),
        exportCheckedKeys = _onTreeNodeCheck2[0],
        exportFilterAnCheckedKeys = _onTreeNodeCheck2[1],
        halfKeysSet = _onTreeNodeCheck2[2];

    var getTargetKeys = function getTargetKeys(targetKeys) {
      return targetKeys.map(function (key) {
        return getTrulyKey(key, numberKeysSetRef.current)[0];
      });
    };

    var _getCheckedNodes = getCheckedNodes(treeNode, newCheckedKeysSet, fieldNames, keyToTreeNodeMapRef.current, numberKeysSetRef.current),
        _getCheckedNodes2 = _slicedToArray(_getCheckedNodes, 1),
        checkedTreeNode = _getCheckedNodes2[0];

    if (!('checkedKeys' in props)) {
      setCheckedKeys(newCheckedKeysSet);
    }

    setHalfCheckedKeys(halfKeysSet);
    onCheck === null || onCheck === void 0 ? void 0 : onCheck(getTargetKeys(exportCheckedKeys), {
      checked: e.target.checked,
      checkedNodes: checkedTreeNode,
      event: 'check',
      nativeEvent: e.nativeEvent,
      checkedChildrenKeys: getTargetKeys(exportFilterAnCheckedKeys)
    });
  };

  var onNodeSelect = function onNodeSelect(e, treeNode) {
    var copyTreeNode = _objectSpread(_objectSpread({}, treeNode), {}, {
      key: getTrulyKey(treeNode.nodeKey, numberKeysSetRef.current)[1]
    });

    currentKeyRef.current = copyTreeNode.nodeKey; // 如果有children就代表数据已经加载过了

    if (loadData && !copyTreeNode.children && !copyTreeNode.isLeaf) {
      setCurLoadingKey(copyTreeNode.nodeKey);
      loadData(copyTreeNode, copyTreeNode.level + 1).then(function () {
        // 数据异步回来之后这里需要获取到最新的treeNode
        var newTreeNode = keyToTreeNodeMapRef.current.get(copyTreeNode.nodeKey);
        setCurLoadingKey(null);
        if (!newTreeNode) return;
        var endCheckedKeys = updateKeys(checkedKeysRef.current);
        nodeSelect(e, newTreeNode, endCheckedKeys);
      });
      return;
    }

    setTreeNodesLevelArray(getNextLevelArray(_toConsumableArray(treeNodesLevelArray), copyTreeNode));
    nodeSelect(e, copyTreeNode, checkedKeys);
  };

  var renderTreeNodes = function renderTreeNodes(treeNodes) {
    if (!treeNodes || !treeNodes.length) return null;
    return treeNodes === null || treeNodes === void 0 ? void 0 : treeNodes.map(function (item, index) {
      return /*#__PURE__*/React.createElement(TreeNodeItem, Object.assign({}, item, {
        // isLeaf={(!item.children && !loadData) || item.isLeaf}
        isLeaf: getNodeIsLeaf(item, !!loadData),
        key: item.nodeKey,
        showIcon: showIcon,
        // icon={icon}
        checkable: checkable,
        loading: loadData && item.nodeKey === curLoadingKey && !item.children,
        selected: selectedKeys.includes(item.nodeKey),
        checked: checkedKeys.has(item.nodeKey),
        indeterminate: halfCheckedKeys.has(item.nodeKey),
        onNodeSelect: onNodeSelect,
        onNodeCheck: onNodeCheck
      }));
    });
  };

  return /*#__PURE__*/React.createElement("div", {
    className: className,
    style: style,
    ref: horizontalTreeRef
  }, (treeNodesLevelArray === null || treeNodesLevelArray === void 0 ? void 0 : treeNodesLevelArray.length) ? treeNodesLevelArray.map(function (levelNodes, index) {
    return (levelNodes === null || levelNodes === void 0 ? void 0 : levelNodes.length) ? /*#__PURE__*/React.createElement("div", {
      // eslint-disable-next-line react/no-array-index-key
      key: index,
      className: "".concat(prefixCls, "-nodes"),
      style: typeof columnWidth !== 'undefined' ? _objectSpread(_objectSpread({}, columnStyle), {}, {
        width: columnWidth
      }) : columnStyle
    }, renderTreeNodes(levelNodes)) : null;
  }) : null);
};

var HorizontalTree = /*#__PURE__*/React.forwardRef(HorizontalTreeRenderFunction);
export default HorizontalTree;