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.Line;
import com.persagy.adm.diagram.core.model.base.Container;
import com.persagy.adm.diagram.core.model.template.MainPipe;

import java.util.*;
import java.util.stream.Collectors;

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

    private Diagram diagram;

    private DataStrategy dataStrategy;

    private List<ObjectNode> rels;

    private List<ObjectNode> optionalObjs;

    private List<ObjectNode> optionalRels;

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

    /**
     * 加载已经保存的数据
     */
    public void initLoad() {
        List<String> objIds = diagram.getObjIds();
        if (objIds.size() > 0) {
            List<ObjectNode> objs = dataStrategy.loadObjectsById(objIds, diagram.getProjectId(), diagram.getGroupCode());
            if (CollUtil.isNotEmpty(objs)) {
                initNodes(objs);
            } else {
                throw new DiagramException("对象数据加载失败");
            }
        }

        List<String> relIds = diagram.getRelIds();
        if (relIds.size() > 0) {
            List<ObjectNode> rels = dataStrategy.loadRelationsById(relIds, diagram.getProjectId(), diagram.getGroupCode());
            if (CollUtil.isNotEmpty(rels)) {
                initLines(rels);
            } else {
                throw new DiagramException("关系数据加载失败");
            }
        }
    }

    private void initNodes(List<ObjectNode> objs) {
        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()));
                } else {
                    en.setLegend(DiagramBuilder.emptyLegend());
                }
            }

            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<>();
        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);
				}
            }
        }
    }

    /**
     * 搜索数据并自动加载
     */
    public void autoLoad(DiagramBuilder builder) {
        //查询备选数据
        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()) {
                //TODO 过滤已经初始化加载数据的干管
                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());
		} else {
			optionalObjs = new ArrayList<>();
		}
        //记录备选对象id列表
        List<String> objIds = optionalObjs.stream().map(obj -> obj.get("id").asText()).collect(Collectors.toList());

        //去掉已经使用的数据项
        HashMap<String, Object> equipMap = builder.getEquipMap();
        if (equipMap.size() > 0) {
			optionalObjs = optionalObjs.stream().filter(obj -> !equipMap.containsKey(obj.get("id").asText())).collect(Collectors.toList());
		}

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

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

        builder.buildLines(optionalRels);
    }

}
