package com.persagy.adm.diagram.core.build;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.persagy.adm.diagram.core.DataStrategy;
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.Line;
import com.persagy.adm.diagram.core.model.base.Container;
import com.persagy.adm.diagram.core.model.template.MainPipe;
import com.persagy.dmp.common.constant.ValidEnum;
import com.persagy.dmp.digital.entity.ObjectRelation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

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

	private Diagram diagram;

	private DataStrategy dataStrategy;

	private LegendLoader legendLoader;

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

	/**
	 * 加载已经保存的数据
	 */
	public void initLoad(){
		List<String> objIds = diagram.getObjIds();
		if(objIds.size() > 0) {
			List<ObjectNode> objs = dataStrategy.loadObjectsById(objIds, diagram.getProjectId(), diagram.getGroupCode());
			initNodes(objs);
		}

		List<String> relIds = diagram.getRelIds();
		if(relIds.size() > 0) {
			List<ObjectNode> rels = dataStrategy.loadRelationsById(relIds, diagram.getProjectId(), diagram.getGroupCode());
			initLines(rels);
		}
	}

	private void initNodes(List<ObjectNode> objs) {
		HashMap<String, ObjectNode> objMap = new HashMap<>();
		if(objs != null) {
			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.getDataObjectId());

				en.setLegend(legendLoader.findLegendById(en.getLegendId(), en.getObjSystemCode()));

				//设置anchorLocations
				en.setAnchorLocations();
			}

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

		//设备类干管
		if(diagram.getTemplate().getMainPipes() != null) {
			for(MainPipe mainPipe : diagram.getTemplate().getMainPipes()) {
				if(mainPipe.isBindEquipment()){
					ObjectNode obj = objMap.get(mainPipe.getDataObjectId());
					if(obj != null) {
						mainPipe.setDataObject(obj);
					}
				}
			}
		}
	}

	private void initLines(List<ObjectNode> rels){
		HashMap<String, ObjectNode> relMap = new HashMap<>();
		if(rels != null) {
			rels.forEach(obj -> relMap.put(obj.get("id").asText(), obj));
		}

		for(Line line : diagram.getLines()) {
			if(line.getDataObjectId() != null){
				ObjectNode rel = relMap.get(line.getDataObjectId());
				if(rel != null) {
					line.setDataObject(rel);
					line.setDataObjectId(rel.get("id").asText());
				}
			}
		}
	}

	/**
	 * 搜索数据并自动加载
	 */
	public void autoLoad(CalcContext context) {
		List<ObjectNode> optionalObjs = null;
		List<ObjectNode> optionalRels = null;

		//查询备选数据
		HashSet<String> equipTypes = new HashSet<>();
		List<Container> containers = diagram.getTemplate().getContainers();
		for(Container con : containers) {
			if(con.getEquipmentTypes() != null) {
				equipTypes.addAll(con.getEquipmentTypes());
			}
		}
		if(diagram.getTemplate().getMainPipes() != null) {
			for(MainPipe mainPipe : diagram.getTemplate().getMainPipes()) {
				if(mainPipe.getEquipmentTypes() != null) {
					equipTypes.addAll(mainPipe.getEquipmentTypes());
				}
			}
		}

		//TODO 打包设备查询性能优化
		if(equipTypes.size() > 0) {
			optionalObjs = dataStrategy.loadObjectsByType(new ArrayList<>(equipTypes), diagram.getProjectId(), diagram.getSystemId(), diagram.getGroupCode());
			optionalObjs = filterValid(optionalObjs);
		}
		context.setOptionalObjs(optionalObjs);

		context.setDataStrategy(dataStrategy);
		legendLoader.setContext(context);
		DiagramBuilder builder = new DiagramBuilder(context, legendLoader);

		builder.buildStructure();
		List<String[]> relTypes = builder.getRefRelTypes().stream().map(type -> type.split("/")).collect(Collectors.toList());

		List<String> objIds = new ArrayList<>(context.getEquipMap().keySet());
		//TODO 关系查询，需要区分打包设备
		if(objIds.size() > 0 && relTypes.size() > 0) {
			optionalRels = dataStrategy.loadRelationsByType(relTypes, objIds, diagram.getProjectId(), diagram.getGroupCode());
			optionalRels = filterValid(optionalRels);
		}
		if(optionalRels == null){
			optionalRels = new ArrayList<>();
		}

		builder.buildLines(optionalRels);
	}

	private List<ObjectNode> filterValid(List<ObjectNode> list){
		if(CollUtil.isEmpty(list))
			return list;

		return list.stream().filter(obj ->
				obj.get(ObjectRelation.PROP_VALID) == null || obj.get(ObjectRelation.PROP_VALID).asInt() == ValidEnum.TRUE.getType())
				.collect(Collectors.toList());
	}

}
