/*
 * @Author: code4eat awesomedema@gmail.com
 * @Date: 2023-02-20 14:31:06
 * @LastEditors: code4eat awesomedema@gmail.com
 * @LastEditTime: 2023-09-21 14:38:08
 * @FilePath: /BudgetManaSystem/src/utils/tooljs.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

let parent: any = undefined;

export const getDeepestTreeData: any = (tree: any, childrenName: string) => {
  if (tree[`${childrenName}`] && tree[`${childrenName}`].length > 0) {
    parent = tree;
    return getDeepestTreeData(tree[`${childrenName}`][0], childrenName);
  }

  return [tree, parent];
};

/*
 * @param x {Object} 对象1
 * @param y {Object} 对象2
 * @return  {Boolean} true 为相等，false 为不等
 */
export const deepEqual = (
  x: { [x: string]: any } | null,
  y: { [x: string]: any; hasOwnProperty?: any } | null,
) => {
  // 指向同一内存时
  if (x === y) {
    return true;
  } else if (
    typeof x == 'object' &&
    x != null &&
    typeof y == 'object' &&
    y != null
  ) {
    if (Object.keys(x).length !== Object.keys(y).length) {
      return false;
    }
    for (var prop in x) {
      if (y.hasOwnProperty(prop)) {
        if (!deepEqual(x[prop], y[prop])) return false;
      } else {
        return false;
      }
    }
    return true;
  } else {
    return false;
  }
};

// 查找父节点的函数

interface Node {
  code: string;
  parentCode: number;
  children?: Node[];
}

export const findAllParents = (data: Node[], parentCode: string): Node[] => {
  let result: Node[] = [];

  function findNodeRecursively(node: Node, path: Node[]): boolean {
    if (node.code === `${parentCode}`) {
      result = [...path, node];
      return true;
    }

    if (node.children) {
      for (const child of node.children) {
        if (findNodeRecursively(child, [...path, node])) {
          return true;
        }
      }
    }

    return false;
  }

  for (const node of data) {
    if (parentCode != '0' && findNodeRecursively(node, [])) {
      break;
    }
  }

  return result;
};

//获取所有children节点的code

interface TreeNode {
  code: string;
  [key: string]: any;
  children?: TreeNode[];
}

export const getNodesWithChildren = (tree: TreeNode[]): TreeNode[] => {
  let nodes: TreeNode[] = [];

  function helper(node: TreeNode) {
    if (node.children && node.children.length > 0) {
      // 当前节点包含 children，添加整个节点
      nodes.push(node);
      // 递归处理子节点
      for (const child of node.children) {
        helper(child);
      }
    }
  }

  // 在这个版本中，我们对每个根节点进行操作
  for (const node of tree) {
    helper(node);
  }

  return nodes;
};

//找出所有父节点的code

export const findParentCodes = (
  node: TreeNode,
  parentCodes: string[] = [],
): string[] => {
  if (node.children && node.children.length > 0) {
    parentCodes.push(node.code);

    for (let child of node.children) {
      findParentCodes(child, parentCodes);
    }
  }

  return parentCodes;
};

//将动态表头转换

type JsonStructure = {
  code: string;
  name: string;
  expand?: number;
  childTitle?: JsonStructure[];
};

type Column = {
  title: string;
  dataIndex: string;
  key: string;
  children?: Column[];
};

export const convertToColumns = (json: JsonStructure[]): Column[] => {
  return json.map((item) => {
    let column: Column = {
      title: item.name,
      dataIndex: item.code,
      key: item.code,
    };

    if (item.expand === 1 && item.childTitle && item.childTitle.length > 0) {
      column.children = convertToColumns(item.childTitle);
    }

    return column;
  });
};

//搜索树结构中叶子节点的某一个属性，并返回所有匹配的集合

export const searchLeaves = (
  nodes: any[],
  keywords: string | undefined,
  keyName: string,
  childrenKey: string,
  results: any[] = [],
): any[] => {
  for (const node of nodes) {
    if (!Array.isArray(node[childrenKey])) {
      if (node[keyName].indexOf(keywords) != -1) {
        results.push(node);
      }
    } else if (Array.isArray(node[childrenKey])) {
      searchLeaves(node[childrenKey], keywords, keyName, childrenKey, results);
    }
  }
  return results;
};

// 获取节点的所有子节点（包含所有层级的子节点）
export const getAllChildren = (
  node: any,
  childrenKey: string = 'children',
): any[] => {
  const children: any[] = [];

  if (node[childrenKey] && Array.isArray(node[childrenKey])) {
    for (const child of node[childrenKey]) {
      children.push(child);
      // 递归获取子节点的子节点
      const grandChildren = getAllChildren(child, childrenKey);
      children.push(...grandChildren);
    }
  }

  return children;
};

// 从选中的节点中获取所有相关节点（包含父节点选中时的所有子节点）
export const getExpandedSelectedNodes = (
  selectedNodes: any[],
  allNodes: any[],
  childrenKey: string = 'children',
): any[] => {
  const expandedNodes: any[] = [];
  const processedIds = new Set();

  for (const selectedNode of selectedNodes) {
    // 如果已经处理过这个节点，跳过
    if (processedIds.has(selectedNode.id)) {
      continue;
    }

    // 添加当前选中的节点
    expandedNodes.push(selectedNode);
    processedIds.add(selectedNode.id);

    // 获取该节点的所有子节点
    const children = getAllChildren(selectedNode, childrenKey);
    for (const child of children) {
      if (!processedIds.has(child.id)) {
        expandedNodes.push(child);
        processedIds.add(child.id);
      }
    }
  }

  return expandedNodes;
};

// 获取节点的父节点
export const getParentNode = (
  nodeKey: React.Key,
  allData: any[],
  childrenKey: string = 'children',
  keyField: string = 'id',
): any | null => {
  const findParent = (
    nodes: any[],
    targetKey: React.Key,
    parent: any = null,
  ): any | null => {
    for (const node of nodes) {
      if (node[keyField] === targetKey) {
        return parent;
      }
      if (node[childrenKey] && Array.isArray(node[childrenKey])) {
        const result = findParent(node[childrenKey], targetKey, node);
        if (result !== null) {
          return result;
        }
      }
    }
    return null;
  };

  return findParent(allData, nodeKey);
};

// 检查父节点的所有子节点是否都被选中
export const areAllChildrenSelected = (
  parentNode: any,
  selectedKeys: Set<React.Key>,
  childrenKey: string = 'children',
  keyField: string = 'id',
): boolean => {
  if (!parentNode[childrenKey] || !Array.isArray(parentNode[childrenKey])) {
    return true; // 没有子节点，认为都被选中
  }

  for (const child of parentNode[childrenKey]) {
    if (!selectedKeys.has(child[keyField])) {
      return false;
    }
    // 递归检查子节点的子节点
    if (!areAllChildrenSelected(child, selectedKeys, childrenKey, keyField)) {
      return false;
    }
  }
  return true;
};

// 处理树形选择的父子联动逻辑
export const handleTreeSelection = (
  selectedRowKeys: React.Key[],
  selectedRows: any[],
  allData: any[],
  prevSelectedKeys: React.Key[] = [],
  childrenKey: string = 'children',
  keyField: string = 'id',
): {
  newSelectedKeys: React.Key[];
  newSelectedRows: any[];
} => {
  const newSelectedKeys = new Set<React.Key>(selectedRowKeys);
  const prevSelectedSet = new Set<React.Key>(prevSelectedKeys);

  // 创建节点映射
  const nodeMap = new Map<React.Key, any>();
  const buildNodeMap = (nodes: any[]) => {
    for (const node of nodes) {
      nodeMap.set(node[keyField], node);
      if (node[childrenKey] && Array.isArray(node[childrenKey])) {
        buildNodeMap(node[childrenKey]);
      }
    }
  };
  buildNodeMap(allData);

  // 找出新增和删除的节点
  const addedKeys = selectedRowKeys.filter((key) => !prevSelectedSet.has(key));
  const removedKeys = prevSelectedKeys.filter(
    (key) => !newSelectedKeys.has(key),
  );

  // 处理新增的节点（勾选时自动勾选子节点）
  for (const key of addedKeys) {
    const node = nodeMap.get(key);
    if (!node) continue;

    // 自动选中所有子节点
    const children = getAllChildren(node, childrenKey);
    for (const child of children) {
      newSelectedKeys.add(child[keyField]);
    }
  }

  // 处理删除的节点（取消勾选时自动取消勾选子节点，并检查父节点）
  for (const key of removedKeys) {
    const node = nodeMap.get(key);
    if (!node) continue;

    // 自动取消选中所有子节点
    const children = getAllChildren(node, childrenKey);
    for (const child of children) {
      newSelectedKeys.delete(child[keyField]);
    }

    // 检查并处理父节点
    let parent = getParentNode(key, allData, childrenKey, keyField);
    while (parent) {
      const parentKey = parent[keyField];
      // 如果父节点当前被选中，但不是所有子节点都被选中，则取消父节点的选中状态
      if (
        newSelectedKeys.has(parentKey) &&
        !areAllChildrenSelected(parent, newSelectedKeys, childrenKey, keyField)
      ) {
        newSelectedKeys.delete(parentKey);
      }
      // 继续检查上级父节点
      parent = getParentNode(parentKey, allData, childrenKey, keyField);
    }
  }

  // 构建新的选中行数据
  const newSelectedRows: any[] = [];
  for (const key of newSelectedKeys) {
    const node = nodeMap.get(key);
    if (node) {
      newSelectedRows.push(node);
    }
  }

  return {
    newSelectedKeys: Array.from(newSelectedKeys),
    newSelectedRows,
  };
};
