import { DataNode, EntityNode, FlattenNode, TreeItemProps } from './type';
import { Dimensions, PixelRatio, StyleSheet } from 'react-native';

/**
 * 平铺树节点使节点可以进行遍历
 */
export function flattenTreeData(treeNodeList: TreeItemProps[] = [], expandedKeys: string[] | true = []): FlattenNode[] {
  const expandedKeySet = new Set(expandedKeys === true ? [] : expandedKeys);
  const flattenList: FlattenNode[] = [];

  //递归遍历每一个节点
  function dig(list: DataNode[], parent: FlattenNode | null = null, show?: boolean): FlattenNode[] {
    return list.map((treeNode) => {
      const mergedKey = treeNode.value;

      const flattenNode: FlattenNode = {
        ...treeNode,
        show,
        parent,
        children: null,
        data: treeNode,
        key: mergedKey,
      };

      flattenList.push(flattenNode);

      // 遍历子节点
      if ((expandedKeys === true || expandedKeySet.has(mergedKey.toString())) && show === true) {
        flattenNode.children = dig(treeNode.children || [], flattenNode, true);
      } else {
        flattenNode.children = dig(treeNode.children || [], flattenNode, false);
      }

      return flattenNode;
    });
  }

  dig(treeNodeList as DataNode[], null, true);
  return flattenList;
}

export function arrDel(list: string[], value: string) {
  const clone = list.slice();
  const index = clone.indexOf(value);
  if (index >= 0) {
    clone.splice(index, 1);
  }
  return clone;
}

export function arrAdd(list: string[], value: string) {
  const clone = list.slice();
  if (clone.indexOf(value) === -1) {
    clone.push(value);
  }
  return clone;
}

/**
 * 获取树组件的props
 */
export function getTreeNodeProps(
  key: string,
  { expandedKeys, checkedKeys }: { expandedKeys: string[]; checkedKeys: string[] },
) {
  const treeNodeProps = {
    eventKey: key,
    expanded: expandedKeys.indexOf(key) !== -1,
    checked: checkedKeys.indexOf(key) !== -1,
  };
  return treeNodeProps;
}

/**
 * 获取节点的数据
 * 用对象形式可以快速查找响应节点
 */
export function getTreeNodeLevel(treeData: TreeItemProps[] = []) {
  const nodeLevel: Record<string, any> = {};

  function processNode(node: TreeItemProps | null, parent?: EntityNode | null) {
    const children = node ? node.children : treeData;

    if (node) {
      nodeLevel[node.value] = {
        level: parent ? parent.level + 1 : 0,
        parent: parent,
        children: children,
        data: node,
        value: node.value,
      };
    }

    if (children) {
      children.forEach((subNode) => {
        processNode(subNode as TreeItemProps, node ? nodeLevel[node?.value] : null);
      });
    }
  }
  processNode(null, null);
  return nodeLevel;
}

/**
 * 填充选中的节点
 */
function fillConductCheck(keys: Set<string>, levelEntities: Map<number, Set<EntityNode>>, maxLevel: number): string[] {
  const checkedKeys = new Set<string>(keys);

  // 从顶部到底部添加选中的键
  for (let level = 0; level <= maxLevel; level += 1) {
    const entities = levelEntities.get(level) || new Set();
    entities.forEach((entity) => {
      const { key, children = [] } = entity;

      if (checkedKeys.has(key)) {
        children?.forEach((childEntity) => {
          checkedKeys.add(childEntity.value);
        });
      }
    });
  }

  // 从下至上添加选中的键
  const visitedKeys = new Set<string>();
  for (let level = maxLevel; level > 0; level -= 1) {
    const entities = levelEntities.get(level) || new Set();
    entities.forEach((entity) => {
      const { parent } = entity;

      let allChecked = true;

      (parent?.children || []).forEach(({ value }) => {
        const checked = checkedKeys.has(value);
        if (allChecked && !checked) {
          allChecked = false;
        }
      });

      if (allChecked) {
        checkedKeys.add(parent.value);
      }

      visitedKeys.add(parent.value);
    });
  }

  return Array.from(checkedKeys);
}

/**
 * 移除取消的节点
 */
function cleanConductCheck(keys: Set<string>, levelEntities: Map<number, Set<EntityNode>>, maxLevel: number): string[] {
  const checkedKeys = new Set<string>(keys);

  // 从上到下删除选中的键
  for (let level = 0; level <= maxLevel; level += 1) {
    const entities = levelEntities.get(level) || new Set();
    entities.forEach((entity) => {
      const { key, children = [] } = entity;

      if (!checkedKeys.has(key)) {
        children?.forEach((childEntity) => {
          checkedKeys.delete(childEntity.value);
        });
      }
    });
  }

  // 从下到上删除选中的键
  const visitedKeys = new Set<string>();
  for (let level = maxLevel; level > 0; level -= 1) {
    const entities = levelEntities.get(level) || new Set();

    entities.forEach((entity) => {
      const { parent } = entity;

      let allChecked = true;

      (parent.children || []).forEach(({ value }) => {
        const checked = checkedKeys.has(value);
        if (allChecked && !checked) {
          allChecked = false;
        }
      });

      if (!allChecked) {
        checkedKeys.delete(parent.value);
      }

      visitedKeys.add(parent.value);
    });
  }

  return Array.from(checkedKeys);
}

/** check时父子组件的关联 */
export function conductCheck(
  keyList: Array<string>,
  keyEntities: Record<string, EntityNode>,
  checked: true | { checked: false },
) {
  // 没有树数据则放回空
  if (!keyList) {
    return [];
  }

  const keys = keyList.filter((key) => {
    return !!keyEntities[key];
  });

  const levelEntities = new Map<number, Set<EntityNode>>();
  let maxLevel = 0;

  //将需要操作的节点根据级别分类
  Object.keys(keyEntities).forEach((key) => {
    const entity = keyEntities[key];
    const { level } = entity;

    let levelSet = levelEntities.get(level);
    if (!levelSet) {
      levelSet = new Set();
      levelEntities.set(level, levelSet);
    }

    levelSet.add(entity);

    //获取最深的级别
    maxLevel = Math.max(maxLevel, level);
  });

  if (checked) {
    let result: string[];
    if (checked === true) {
      result = fillConductCheck(new Set(keys), levelEntities, maxLevel);
    } else {
      result = cleanConductCheck(new Set(keys), levelEntities, maxLevel);
    }

    return result;
  }
  return [];
}
