package com.persagy.adm.diagram.service;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.persagy.adm.diagram.client.DicClient;
import com.persagy.adm.diagram.util.Pagination;
import com.persagy.adm.diagram.util.ServiceUtil;
import com.persagy.adm.diagram.client.RwdClient;
import com.persagy.adm.diagram.frame.BdtpRequest;
import com.persagy.dmp.basic.model.QueryCriteria;
import com.persagy.dmp.define.entity.GraphDefine;
import com.persagy.dmp.define.entity.RelationDefine;
import com.persagy.dmp.digital.client.DigitalObjectClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * bdtp数据服务调用服务封装
 */
@Service
public class BdtpDataService {

	@Autowired
	private RwdClient rwdClient;

	@Autowired
	private DicClient dicClient;

	@Autowired
	private DigitalObjectClient objectClient;

	@Autowired
	private ObjectMapper objectMapper;

	public List<ObjectNode> getMajorList(BdtpRequest req){
		//查询专业定义
		QueryCriteria majorCriteria = ServiceUtil.getQueryCriteria(objectMapper);
		majorCriteria.getCriteria().put("type", "major");
		return ServiceUtil.call (() -> dicClient.dataQuery(req.getGroupCode(), req.getProjectId(), req.getAppId(), req.getUserId(), majorCriteria));
	}

	public List<ObjectNode> getSystemList(BdtpRequest req){
		//查询系统定义
		QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper, "system");
		return ServiceUtil.queryAllPage(() -> rwdClient.queryObjectType(req.getGroupCode(), req.getProjectId(), req.getAppId(), req.getUserId(), criteria), criteria, new Pagination(500));
	}

	/**
	 * 查询系统下的设备类型定义
	 */
	public List<ObjectNode> getEquipTypeList(BdtpRequest req, String system){
		QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper, "equipment");
		if(StrUtil.isNotBlank(system))
			criteria.getCriteria().put("systemCode", system);
		return ServiceUtil.queryAllPage(() -> rwdClient.queryObjectType(req.getGroupCode(), req.getProjectId(), req.getAppId(), req.getUserId(), criteria), criteria, new Pagination(500));
	}

	/**
	 * 查询数据字典关系类型
	 */
	public List<Map<String, Object>> getRelTypeTree(BdtpRequest req){
		List<RelationDefine> relList = ServiceUtil.call(() -> rwdClient.queryRelDef(req.getGroupCode(), req.getProjectId(), req.getAppId(), req.getUserId(), new QueryCriteria()));
		List<GraphDefine> graph = ServiceUtil.call (() -> rwdClient.queryGraphDef(req.getGroupCode(), req.getProjectId(), req.getAppId(), req.getUserId(), new QueryCriteria()));

		List<Map<String, Object>> rels = new ArrayList<>();
		for(GraphDefine gd : graph){
			HashMap<String, Object> m = new HashMap<>();
			m.put("code", gd.getCode());
			m.put("name", gd.getName());
			m.put("type", "graph");
			rels.add(m);

			ArrayList<RelationDefine> chidren = new ArrayList<>();
			m.put("children", chidren);
			for(RelationDefine relDef : relList) {
				if(relDef.getGraphCode().equals(gd.getCode()))
					chidren.add(relDef);
			}
		}
		return rels;
	}

	public List<ObjectNode> queryObjectsByType(BdtpRequest req, List<String> equipmentTypes, String systemId){
		QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper, "equipment");

		ArrayNode types = criteria.getCriteria().putArray("classCode");
		for(String code : equipmentTypes) {
			types.add(code);
		}

		if(StrUtil.isNotBlank(systemId)){
			//TODO 按系统实例进行过滤
		}

		List<ObjectNode> objs = ServiceUtil.queryAllPage(() -> objectClient.query(req.getGroupCode(), req.getProjectId(), req.getAppId(), req.getUserId(), criteria), criteria, new Pagination(500));
		if(objs == null)
			objs = new ArrayList<>(0);
		return objs;
	}

	public List<ObjectNode> queryObjectsById(BdtpRequest req, List<String> ids){
		QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper, "equipment");
		ArrayNode arr = criteria.getCriteria().putArray("id");
		for(String id : ids) {
			arr.add(id);
		}

		List<ObjectNode> objs = ServiceUtil.queryAllPage(() -> objectClient.query(req.getGroupCode(), req.getProjectId(), req.getAppId(), req.getUserId(), criteria), criteria, new Pagination(500));
		if(objs == null)
			objs = new ArrayList<>(0);
		return objs;
	}

	public List<ObjectNode> queryRelsByTypeAndObj(BdtpRequest req, List<String[]> relTypes, List<String> objIds){
		List<ObjectNode> rtn = new ArrayList<>();

		QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper);
		ArrayNode arr = criteria.getCriteria().putArray("objFrom");
		for(String id : objIds) {
			arr.add(id);
		}
		List<ObjectNode> rels = ServiceUtil.queryAllPage(() -> rwdClient.queryRelation(req.getGroupCode(), req.getProjectId(), req.getAppId(), req.getUserId(), criteria), criteria, new Pagination(500));
		if(rels != null)
			rtn.addAll(rels);

		criteria.getCriteria().set("objTo", criteria.getCriteria().remove("objFrom"));
		rels = ServiceUtil.queryAllPage(() -> rwdClient.queryRelation(req.getGroupCode(), req.getProjectId(), req.getAppId(), req.getUserId(), criteria), criteria, new Pagination(500));
		if(rels != null)
			rtn.addAll(rels);

		//TODO relTypes参数处理

		return rtn;
	}

}
