"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const types = require("../../../../utils/types.js");
const util = require("../util.js");
const vue = require("vue");
const shared_esmBundler = require("../../../../../../@vue/shared/dist/shared.esm-bundler.js");
function useTree(watcherData) {
  const expandRowKeys = vue.ref([]);
  const treeData = vue.ref({});
  const indent = vue.ref(16);
  const lazy = vue.ref(false);
  const lazyTreeNodeMap = vue.ref({});
  const lazyColumnIdentifier = vue.ref("hasChildren");
  const childrenColumnName = vue.ref("children");
  const checkStrictly = vue.ref(false);
  const instance = vue.getCurrentInstance();
  const normalizedData = vue.computed(() => {
    if (!watcherData.rowKey.value) return {};
    return normalize(watcherData.data.value || []);
  });
  const normalizedLazyNode = vue.computed(() => {
    const rowKey = watcherData.rowKey.value;
    const keys = Object.keys(lazyTreeNodeMap.value);
    const res = {};
    if (!keys.length) return res;
    keys.forEach((key) => {
      if (lazyTreeNodeMap.value[key].length) {
        const item = { children: [] };
        lazyTreeNodeMap.value[key].forEach((row) => {
          const currentRowKey = util.getRowIdentity(row, rowKey);
          item.children.push(currentRowKey);
          if (row[lazyColumnIdentifier.value] && !res[currentRowKey]) res[currentRowKey] = { children: [] };
        });
        res[key] = item;
      }
    });
    return res;
  });
  const normalize = (data) => {
    const rowKey = watcherData.rowKey.value;
    const res = {};
    util.walkTreeNode(data, (parent, children, level) => {
      const parentId = util.getRowIdentity(parent, rowKey);
      if (shared_esmBundler.isArray(children)) res[parentId] = {
        children: children.map((row) => util.getRowIdentity(row, rowKey)),
        level
      };
      else if (lazy.value) res[parentId] = {
        children: [],
        lazy: true,
        level
      };
    }, childrenColumnName.value, lazyColumnIdentifier.value, lazy.value);
    return res;
  };
  const updateTreeData = (ifChangeExpandRowKeys = false, ifExpandAll) => {
    var _a, _b;
    ifExpandAll || (ifExpandAll = (_a = instance.store) == null ? void 0 : _a.states.defaultExpandAll.value);
    const nested = normalizedData.value;
    const normalizedLazyNode_ = normalizedLazyNode.value;
    const keys = Object.keys(nested);
    const newTreeData = {};
    if (keys.length) {
      const oldTreeData = vue.unref(treeData);
      const rootLazyRowKeys = [];
      const getExpanded = (oldValue, key) => {
        if (ifChangeExpandRowKeys) if (expandRowKeys.value) return ifExpandAll || expandRowKeys.value.includes(key);
        else return !!(ifExpandAll || (oldValue == null ? void 0 : oldValue.expanded));
        else {
          const included = ifExpandAll || expandRowKeys.value && expandRowKeys.value.includes(key);
          return !!((oldValue == null ? void 0 : oldValue.expanded) || included);
        }
      };
      keys.forEach((key) => {
        const oldValue = oldTreeData[key];
        const newValue = { ...nested[key] };
        newValue.expanded = getExpanded(oldValue, key);
        if (newValue.lazy) {
          const { loaded = false, loading = false } = oldValue || {};
          newValue.loaded = !!loaded;
          newValue.loading = !!loading;
          rootLazyRowKeys.push(key);
        }
        newTreeData[key] = newValue;
      });
      const lazyKeys = Object.keys(normalizedLazyNode_);
      if (lazy.value && lazyKeys.length && rootLazyRowKeys.length) lazyKeys.forEach((key) => {
        var _a2;
        const oldValue = oldTreeData[key];
        const lazyNodeChildren = normalizedLazyNode_[key].children;
        if (rootLazyRowKeys.includes(key)) {
          if (((_a2 = newTreeData[key].children) == null ? void 0 : _a2.length) !== 0) throw new Error("[ElTable]children must be an empty array.");
          newTreeData[key].children = lazyNodeChildren;
        } else {
          const { loaded = false, loading = false } = oldValue || {};
          newTreeData[key] = {
            lazy: true,
            loaded: !!loaded,
            loading: !!loading,
            expanded: getExpanded(oldValue, key),
            children: lazyNodeChildren,
            level: void 0
          };
        }
      });
    }
    treeData.value = newTreeData;
    (_b = instance.store) == null ? void 0 : _b.updateTableScrollY();
  };
  vue.watch(() => expandRowKeys.value, () => {
    updateTreeData(true);
  }, { deep: true });
  vue.watch(() => normalizedData.value, () => {
    updateTreeData();
  });
  vue.watch(() => normalizedLazyNode.value, () => {
    updateTreeData();
  });
  const updateTreeExpandKeys = (value) => {
    expandRowKeys.value = value;
    updateTreeData();
  };
  const isUseLazy = (data) => {
    return lazy.value && data && "loaded" in data && !data.loaded;
  };
  const toggleTreeExpansion = (row, expanded) => {
    instance.store.assertRowKey();
    const rowKey = watcherData.rowKey.value;
    const id = util.getRowIdentity(row, rowKey);
    const data = id && treeData.value[id];
    if (id && data && "expanded" in data) {
      const oldExpanded = data.expanded;
      expanded = types.isUndefined(expanded) ? !data.expanded : expanded;
      treeData.value[id].expanded = expanded;
      if (oldExpanded !== expanded) instance.emit("expand-change", row, expanded);
      expanded && isUseLazy(data) && loadData(row, id, data);
      instance.store.updateTableScrollY();
    }
  };
  const loadOrToggle = (row) => {
    instance.store.assertRowKey();
    const rowKey = watcherData.rowKey.value;
    const id = util.getRowIdentity(row, rowKey);
    const data = treeData.value[id];
    if (isUseLazy(data)) loadData(row, id, data);
    else toggleTreeExpansion(row, void 0);
  };
  const loadData = (row, key, treeNode) => {
    const { load } = instance.props;
    if (load && !treeData.value[key].loaded) {
      treeData.value[key].loading = true;
      load(row, treeNode, (data) => {
        if (!shared_esmBundler.isArray(data)) throw new TypeError("[ElTable] data must be an array");
        treeData.value[key].loading = false;
        treeData.value[key].loaded = true;
        treeData.value[key].expanded = true;
        if (data.length) lazyTreeNodeMap.value[key] = data;
        instance.emit("expand-change", row, true);
      });
    }
  };
  const updateKeyChildren = (key, data) => {
    const { lazy: lazy2, rowKey } = instance.props;
    if (!lazy2) return;
    if (!rowKey) throw new Error("[Table] rowKey is required in updateKeyChild");
    if (lazyTreeNodeMap.value[key]) lazyTreeNodeMap.value[key] = data;
  };
  return {
    loadData,
    loadOrToggle,
    toggleTreeExpansion,
    updateTreeExpandKeys,
    updateTreeData,
    updateKeyChildren,
    normalize,
    states: {
      expandRowKeys,
      treeData,
      indent,
      lazy,
      lazyTreeNodeMap,
      lazyColumnIdentifier,
      childrenColumnName,
      checkStrictly
    }
  };
}
exports.default = useTree;
