package com.app.framework.core.support.convert;

import cn.hutool.core.util.TypeUtil;
import com.app.framework.core.support.view.tree.ExTreeNode;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

/**
 * Entity转TreeNode工具类
 * 	用法：继承该类，并实现convert(E entity, T view)方法
 * 
 * @param <E> Entity
 * @param <T> TreeNode
 */
public abstract class ConvertTreeNodeUtils<E, T extends ExTreeNode> {
	
	protected Class<T> viewClass;
	private LinkedHashMap<String, T> retp = new LinkedHashMap<String, T>();
	
	@SuppressWarnings("unchecked")
	public ConvertTreeNodeUtils() {
		viewClass = (Class) TypeUtil.getTypeArgument(getClass(), 1);
	}
	
	/**
	 * 将Entity转换为TreeNode
	 * @param entity	要转换的Entity对象
	 */
	public T transTreeNode(E entity) {
		try {
			T node = viewClass.newInstance();
			if (entity != null) {
				convert(entity, node);
			}
			return node;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 将Entity集合转换为TreeNode集合
	 * @param list	要转换的Entity集合
	 */
	public List<T> transTreeNode(List<E> list) {
		int size = list != null ? list.size() : 0;
		List<T> result = new ArrayList<>(size);
		try {
			for (int i = 0; i < size; i++) {
				E entity = list.get(i);
				T node = viewClass.newInstance();
				convert(entity, node);
				result.add(node);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 将Entity集合转换为TreeNode集合，静态树
	 * @param list 要转换的Entity集合
	 */
	public List<T> transStaticTree(List<E> list) {
		return transStaticTree(list, null, null);
	}

	/**
	 * 将Entity集合转换为TreeNode集合，静态树
	 * @param list 要转换的Entity集合
	 * @param checkedOidSet 已选择的节点OID集合
	 */
	public List<T> transStaticTree(List<E> list, Set<String> checkedOidSet) {
		return transStaticTree(list, null, checkedOidSet);
	}

	/**
	 * 将Entity集合转换为TreeNode集合，静态树
	 * @param list 要转换的Entity集合
	 * @param root 添加一个根节点
	 * @param checkedOidSet 已选择的节点OID集合
	 */
	public List<T> transStaticTree(List<E> list, T root, Set<String> checkedOidSet) {
		int size = list != null ? list.size() : 0;
		ArrayList<T> treeNodes;
		if(null != root){
			treeNodes = new ArrayList<T>(size + 1);
			root.setParentId(null);
			treeNodes.add(root);
		}else{
			treeNodes = new ArrayList<>(size);
		}
		try {
			for (int i = 0; i < size; i++) {
				E entity = list.get(i);
				T node = viewClass.newInstance();
				convert(entity, node);
				if(node.getId() == null){
					throw new Exception("TreeNode id is null");
				}
				nodeCheck(node, checkedOidSet);
				if(null != root && node.getId().equals(root.getId())){//根节点
					//此时根节点已在treeNodes中，不能再次加入
				}else{
					treeNodes.add(node);
				}
				if(node.getParentId() != null && !node.getParentId().equals("0")){
					retp.put(node.getId(), node);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return transStaticTree(treeNodes);
	}

	/**
	 * 将TreeNode集合生成静态树，静态树
	 * @param list	要转换的TreeNode集合
	 */
	private List<T> transStaticTree(ArrayList<T> list) {
		int size = list != null ? list.size() : 0;
		if(retp.size() < 1){
			for (int i = 0; i < size; i++) {
				T node = list.get(i);
				if(node.getParentId() != null && !node.getParentId().equals("0")){
					retp.put(node.getId(), node);
				}
			}
		}
		List<T> completeTree = new ArrayList<T>();
		for (int i = 0; i < size; i++) {
			T node = list.get(i);
			if (node.getParentId() == null || node.getParentId().equals("0")) {
				node = node.buildTree(node, retp);
				completeTree.add(node);
			}
		}
		retp.clear();
		return completeTree;
	}
	
	/**
	 * 自定义转换
	 * @param entity	Entity对象
	 * @param node	TreeNode对象
	 */
	public abstract void convert(E entity, T node);

	/**
	 * 设置节点是否选中
	 * 	子类可自行重写
	 * @param node 节点
	 * @param checkedOidSet 选中的ID集合
	 */
	public void nodeCheck(T node, Set<String> checkedOidSet){

	}
}
