package com.persagy.adm.diagram.core;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.persagy.adm.diagram.core.model.Diagram;
import com.persagy.adm.diagram.core.model.DiagramNode;
import com.persagy.adm.diagram.core.model.EquipmentNode;
import com.persagy.adm.diagram.core.model.base.Container;
import com.persagy.adm.diagram.core.model.logic.DataFilter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * 系统图数据加载
 * @author zhaoyk
 */
public class DiagramDataLoader {

	private Diagram diagram;

	private DataStrategy dataStrategy;

	private List<Container> containers;

	private List<ObjectNode> objs;

	private List<ObjectNode> rels;

	private List<ObjectNode> optionalObjs;

	private List<ObjectNode> optionalRels;

	private DiagramBuilder builder;

	public DiagramDataLoader(Diagram diagram, DataStrategy dataStrategy) {
		this.diagram = diagram;
		this.dataStrategy = dataStrategy;
		this.builder = new DiagramBuilder(diagram, dataStrategy);
	}

	public void load(){
		List<String> objIds = diagram.getObjIds();
		if(objIds.size() > 0)
			objs = dataStrategy.loadObjectsById(objIds, diagram.getProjectId(), diagram.getGroupCode());
		else
			objs = new ArrayList<>();
		buildNodes();
	}

	private void buildNodes() {
		HashMap<String, ObjectNode> objMap = new HashMap<>();
		objs.forEach(obj -> objMap.put(obj.get("id").asText(), obj));

		for (DiagramNode node : diagram.getNodes()) {
			ObjectNode obj = null;

			if(EquipmentNode.TYPE.equals(node.getCompType())) { //设备节点
				EquipmentNode en = (EquipmentNode) node;
				obj = objMap.get(en.getObjId());

				if(en.getLegendId() != null)
					en.setLegend(dataStrategy.getLegend(en.getLegendId(), en.getObjSystemCode()));
			}

			if(obj != null)
				node.setDataObject(obj);
		}
	}

	public void autoLoad() {
		//查询备选数据
		List<String> equipTypes = new ArrayList<>();
		if (diagram.getTemplate() != null) {
			containers = diagram.getTemplate().getContainers();
			for(Container con : containers) {
				loadEquipTypes(con, equipTypes);
			}
		} else
			containers = new ArrayList<>();

		//TODO 数据查询，需要区分打包设备
		if(equipTypes.size() > 0)
			optionalObjs = dataStrategy.loadObjectsByType(equipTypes, diagram.getProjectId(), diagram.getSystemId(), diagram.getGroupCode());
		else
			optionalObjs = new ArrayList<>();

		//去掉已经使用的数据项
		HashMap<String, DiagramNode> nodeMap = new HashMap<>();
		diagram.getNodes().forEach(node -> {
			if(EquipmentNode.TYPE.equals(node.getCompType()))
				nodeMap.put(((EquipmentNode) node).getObjId(), node);
		});
		if(nodeMap.size() > 0) {
			Iterator<ObjectNode> iter = optionalObjs.iterator();
			while (iter.hasNext()) {
				ObjectNode obj = iter.next();
				if(nodeMap.containsKey(obj.get("id").asText()))
					iter.remove();
			}
		}

		addEquipNodes();
		buildContainers();

		//TODO 关系查询，需要区分打包设备
//		if(optionalObjs.size() > 0) {
//			List<String> objIds = new ArrayList<>(optionalObjs.size());
//			optionalObjs.forEach(obj -> objIds.add(obj.get("id").asText()));
//			optionalRels = dataStrategy.loadRelationsByType(null, objIds, diagram.getProjectId(), diagram.getGroupCode());
//		} else
//			optionalRels = new ArrayList<>();

		addLines();
	}

	private void loadEquipTypes(Container con, List<String> types){
		if (con.getEquipmentTypes() != null) {
			for (String type : con.getEquipmentTypes()) {
				if (!types.contains(type))
					types.add(type);
			}
		}
	}

	private void addEquipNodes(){
		for(Container con : containers) {
			for(ObjectNode obj : optionalObjs){
				if (match(obj, con)) {
					if(con.getEquipPack() != null)
						builder.addPackData(con, obj);
					else
						builder.addEquipNode(con, obj);
				}
			}
		}

		//test code
//		for(ObjectNode obj : optionalObjs){
//			EquipmentNode node = new EquipmentNode();
//			node.setId(IdUtil.simpleUUID());
//			node.setObjId(obj.get("id").asText());
//			node.setObjClassCode(obj.get("classCode").asText());
//			node.setDataObject(obj);
//
//			Label label = new Label();
//			String content = null;
//			if(obj.get("localName") != null)
//				content = obj.get("localName").asText();
//			if(StrUtil.isBlank(content))
//				content = obj.get("name").asText();
//			label.setContent(content);
//			node.setLabel(label);
//
//			Container con = findContainer(node, obj);
//			if(con != null) {
//				diagram.getNodes().add(node);
//
//				con.addComp(node);
//				node.setContainerId(con.getId());
//				node.setLayoutIndex(con.getChildren().size() - 1);
//
//				Legend legend = findLegend(node, obj);
//				if(legend != null) {
//					node.setLegendId(legend.getId());
//					node.setLegend(legend);
//				}
//			}
//		}
	}

	//test code
//	private Container findContainer(EquipmentNode node, ObjectNode obj){
//		if(containers != null) {
//			for(Container con : containers) {
//				if(con.getEquipmentTypes() != null && con.getEquipmentTypes().contains(node.getObjClassCode())) {
//					if(con.getChildren() == null || con.getChildren().size() == 0)
//						return con;
//				}
//			}
//		}
//		return null;
//	}

	private boolean match(ObjectNode obj, Container con) {
		String classCode = DiagramBuilder.getClassCode(obj);
		if(con.getEquipmentTypes() != null && con.getEquipmentTypes().contains(classCode)) {
			DataFilter filter = con.getDataFilter();
			if(filter != null)
				return filter.filter(obj);
			return true;
		}
		return false;
	}

	private void buildContainers() {
		for(Container con : containers) {
			if(con.isEquipmentBox()) {
				if(Boolean.TRUE.equals(con.getProp(Container.PROP_AUTO_HIDDEN)) && CollUtil.isEmpty(con.getChildren()))
					con.setHidden(true);
			}
		}
	}

	private void addLines(){
		//System.out.println(optionalRels);
	}

}
