package com.yeejoin.equipmanage.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.equipmanage.common.entity.EquipmentSpecificAlarm;
import com.yeejoin.equipmanage.common.entity.EquipmentSpecificIndex;
import com.yeejoin.equipmanage.common.entity.dto.TopographyLineDTO;
import com.yeejoin.equipmanage.common.entity.dto.TopographyNodeDTO;
import com.yeejoin.equipmanage.common.entity.dto.TopographyNodeDetailDTO;
import com.yeejoin.equipmanage.common.entity.dto.TopographyTreeDTO;
import com.yeejoin.equipmanage.common.enums.AbnormalStateEnum;
import com.yeejoin.equipmanage.common.utils.DateUtils;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.foundation.utils.TreeBuilder;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

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

//import net.sf.json.JSONObject;

/**
 * <p>
 * 服务类
 * </p>
 *
 * @author gwb
 * @since 2021-10-14
 */
@Component
public class TopographyService
{

	// 拓扑树根节点code
	public static final String ROOT = "0";

	@Autowired
	private TopographyTreeService topographyTreeService;

	@Autowired
	private TopographyNodeService topographyNodeService;

	@Autowired
	private TopographyLineService topographyLineService;
	
	@Autowired
	private TopographyNodeDetailService topographyNodeDetailService;

	@Autowired
	private EmqKeeper emqKeeper;
	
	// @Autowired
	// private RemoteWebSocketServer webSocketServer;
	//
	// @Autowired
	// RemoteSecurityService remoteSecurityService;
	//
	// public TopographyServiceImpl(ITopographyTreeRepository repository) {
	// super(repository);
	// this.iTopographyTreeDao = repository;
	// }

	/**
	 * 
	 * <pre>
	 * 根据类型获取拓扑树结构
	 * </pre>
	 *
	 * @param type
	 * @return
	 */
	public Collection<TopographyTreeDTO> getTree(int type)
	{

		Collection<TopographyTreeDTO> list = topographyTreeService
				.queryForListByType(type);
		return TreeBuilder.buildByRecursive(list, ROOT);
	}
	//
	// private TopographyTreeDTO convert(TopographyTree node) {
	// TopographyTreeDTO topographyTreeDTO = new TopographyTreeDTO();
	// topographyTreeDTO.setId(node.getCode());
	// topographyTreeDTO.setName(node.getName());
	// topographyTreeDTO.setParent(node.getParentCode());
	// topographyTreeDTO.setTreeCode(node.getTreeCode());
	// topographyTreeDTO.setGroup(node.getGroup());
	// topographyTreeDTO.setOrgCode(node.getOrgCode());
	// return topographyTreeDTO;
	// }

	/**
	 * 
	 * <pre>
	 * 根据装备id更新拓扑节点实时数据及告警状态
	 * </pre>
	 *
	 * @param equipmentSpecificId  装备id
	 * @param indexList 性能指标实时数据
	 * @param alarmList 告警列表数据
	 */
	public void updateNodeDateByEquipId(Long equipmentSpecificId, List<EquipmentSpecificIndex> indexList,
			List<EquipmentSpecificAlarm> alarmList)
	{
		//构建性能指标信息
		List<Map<String, String>> nodeDetail = new ArrayList<>();
		for (EquipmentSpecificIndex equipmentSpecificIndex : indexList)
		{
			Map<String, String> value = new HashMap<String, String>();
			value.put("name", equipmentSpecificIndex.getEquipmentIndexName());
			if (ValidationUtil.isEmpty(equipmentSpecificIndex.getIndexUnitName()))
			{
				String enumStr = equipmentSpecificIndex.getValueEnum();
				if (ObjectUtils.isEmpty(enumStr)) {
					value.put("value", equipmentSpecificIndex.getValue());
				} else {
					try {
						JSONArray jsonArray = JSONArray.parseArray(enumStr);
						for (int i = 0; i < jsonArray.size(); i++) {
							JSONObject jsonObject = jsonArray.getJSONObject(i);
							if (jsonObject.get("key").equals(equipmentSpecificIndex.getValue())) {
								value.put("value", jsonObject.getString("label"));
							}
						}
					} catch (Exception e) {
						value.put("value", equipmentSpecificIndex.getValue());
					}
				}
			}else
			{
				value.put("value", equipmentSpecificIndex.getValue() + equipmentSpecificIndex.getIndexUnitName());
			}
			if (!ValidationUtil.isEmpty(equipmentSpecificIndex.getValue())){
				nodeDetail.add(value);
			}
		}
		/**
		 * 更新节点详情信息
		 */
		List<TopographyNodeDetailDTO> nodeDetailList = topographyNodeDetailService.queryByEqpId(equipmentSpecificId);
		for (TopographyNodeDetailDTO topographyNodeDetailDTO : nodeDetailList)
		{
			//构建告警信息
			if (ValidationUtil.isEmpty(alarmList))
			{
				Map<String, String> value = new HashMap<String, String>();
				value.put("name", "设备状态");
				value.put("value", "正常");
				nodeDetail.add(value);
				//更新node状态
				TopographyNodeDTO topographyNodeDTO = topographyNodeService.queryById(topographyNodeDetailDTO.getNodeid());
				if (topographyNodeDTO.getState() == 1)
				{
					topographyNodeDTO.setState(0);
				}
				topographyNodeDTO.setNumber(alarmList.size());
				topographyNodeService.updateWithModel(topographyNodeDTO);
			}else 
			{
				Map<String, String> value = new HashMap<String, String>();
				value.put("name", "设备状态");
				value.put("value", "告警");
				nodeDetail.add(value);
				//更新node状态
				TopographyNodeDTO topographyNodeDTO = topographyNodeService.queryById(topographyNodeDetailDTO.getNodeid());
				if (topographyNodeDTO.getState() == 0)
				{
					topographyNodeDTO.setState(1);
				}
				topographyNodeDTO.setNumber(alarmList.size());
				topographyNodeService.updateWithModel(topographyNodeDTO);
			}
			if (!ValidationUtil.isEmpty(nodeDetailList)){
				Map<String, String> createDateMap = new HashMap<>();
				createDateMap.put("name", "更新时间");
				createDateMap.put("value", DateUtils.date2LongStr(new Date()));
				nodeDetail.add(createDateMap);
			}
			topographyNodeDetailDTO.setNodeDetail(JSON.toJSONString(nodeDetail));
			topographyNodeDetailDTO.setAlarmNumber(alarmList.size());
			topographyNodeDetailService.updateWithModel(topographyNodeDetailDTO);

			notifyUpdateTopography(topographyNodeDetailDTO);
		}
	}

	@SneakyThrows
	@Async
	public void notifyUpdateTopography(TopographyNodeDetailDTO topographyNodeDetailDTO) {
		try {
			emqKeeper.getMqttClient().publish("notify/equipment/topography", JSONObject.toJSONString(topographyNodeDetailDTO).getBytes(), 0, false);
		} catch (Exception e) {
		}
	}


	/**
	 * 
	 * <pre>
	 * 根据树选中节点及类型获取拓扑节点
	 * </pre>
	 *
	 * @param treeid
	 * @param type
	 * @return
	 */
	public List<TopographyNodeDTO> getNodes(String treeid, int type)
	{
		List<TopographyNodeDTO> nodes = topographyNodeService.queryForListByTypeAndTreeid(type, treeid);
		return nodes.stream().map(t -> convert(t)).collect(Collectors.toList());
	}

	  private TopographyNodeDTO convert(TopographyNodeDTO node) 
	  {
		    TopographyNodeDTO topographyNodeDTO = new TopographyNodeDTO();
		    BeanUtils.copyProperties(node, topographyNodeDTO);
	        topographyNodeDTO.setWarnState(node.getState());
	        topographyNodeDTO.setKey(node.getNodeKey());
			topographyNodeDTO.setGroup(node.getTopoGroup());
			topographyNodeDTO.setWarnState(node.getState());
			if (node.getState() != 0 && !ValidationUtil.isEmpty(node.getNumber())) 
			{
//		        topographyNodeDTO.setWarnMessage(node.getNumber() + AbnormalStateEnum.getText(node.getState()));
				topographyNodeDTO.setWarnMessage(String.valueOf(node.getNumber()));
		    }
	        return topographyNodeDTO;
	    }
	  
	// private TopographyNodeDTO convert(TopographyNode node) {
	// TopographyNodeDTO topographyNodeDTO = new TopographyNodeDTO();
	// BeanUtils.copyProperties(node, topographyNodeDTO);
	// topographyNodeDTO.setWarnState(node.getState());
	// topographyNodeDTO.setPorts(node.getPorts());
	// if (node.getState() != 0) {
	// topographyNodeDTO.setWarnMessage(node.getNumber() +
	// AbnormalStateEnum.getText(node.getState()));
	// }
	// return topographyNodeDTO;
	// }

	/**
	 * 
	 * <pre>
	 * 根据树选中节点及类型获取拓扑链路
	 * </pre>
	 *
	 * @param treeid
	 * @param type
	 * @return
	 */
	public List<TopographyLineDTO> getLinks(String treeid, int type)
	{
		List<TopographyLineDTO> links = topographyLineService.queryForListByTypeAndTreeid(type, treeid);
		return links.stream().map(t -> convert(t)).collect(Collectors.toList());
	}

	private TopographyLineDTO convert(TopographyLineDTO topographyLineDTO) 
	{
		topographyLineDTO.setFrom(topographyLineDTO.getLineFrom());
		topographyLineDTO.setTo(topographyLineDTO.getLineTo());
		topographyLineDTO.setWarnState(topographyLineDTO.getState());
		if (topographyLineDTO.getState() != 0) 
		{
			topographyLineDTO.setWarnMessage(topographyLineDTO.getNumber() + AbnormalStateEnum.getText(topographyLineDTO.getState()));
		}
        return topographyLineDTO;
    }
	
	// private TopographyLineDTO convert(TopographyLine node) {
	// TopographyLineDTO topographyLineDTO = new TopographyLineDTO();
	// BeanUtils.copyProperties(node, topographyLineDTO);
	// topographyLineDTO.setWarnState(node.getState());
	// if (node.getState() != 0) {
	// topographyLineDTO.setWarnMessage(node.getNumber() +
	// AbnormalStateEnum.getText(node.getState()));
	// }
	// return topographyLineDTO;
	// }
	
	/**
	 * 
	 * <pre>
	 * 保存网络拓扑
	 * </pre>
	 *
	 * @param nodeData
	 */
	public void saveNodes(List<TopographyNodeDTO> nodeData)
	{
		for (TopographyNodeDTO topographyNodeDTO : nodeData)
		{
			TopographyNodeDTO oldTopographyNodeDTO = topographyNodeService.queryById(topographyNodeDTO.getId());
			if (!ValidationUtil.isEmpty(oldTopographyNodeDTO))
			{
				oldTopographyNodeDTO.setLoc(topographyNodeDTO.getLoc());
				oldTopographyNodeDTO.setSize(topographyNodeDTO.getSize());
				topographyNodeService.updateWithModel(oldTopographyNodeDTO);
			}
			
		}
	}
	
	// @Override
	// public String getSelfOrgCode() {
	// List<DictionarieValueModel> listDictionaryByDictCode =
	// remoteSecurityService.listDictionaryByDictCode(BNAK_ORG_KEY);
	// StringBuffer sb = new StringBuffer();
	// listDictionaryByDictCode.forEach(e ->{
	// if(BNAK_XIAN_KEY.equals(e.getDictDataKey())||BNAK_KEJICHU_KEY.equals(e.getDictDataKey()))
	// {
	// sb.append('#').append(e.getDictDataValue());
	// }
	// });
	// return sb.toString();
	//
	// }
	//
	// @Override
	// public List<TopographyEventDTO> getEvents() {
	// return iTopographyEventDao.findAll().stream().map(t ->
	// convert(t)).collect(Collectors.toList());
	// }
	//
	// private TopographyEventDTO convert(TopographyEvent t) {
	// TopographyEventDTO topographyEventDTO = new TopographyEventDTO();
	// BeanUtils.copyProperties(t, topographyEventDTO);
	// return topographyEventDTO;
	// }
	//
	// /**
	// * @param sourceId
	// * @param state true 确认告警，false 清除告警
	// */
	// @Override
	// public void sendAbnormal(String sourceId, int state) {
	// TopographyNode node = iTopographyNodeDao.findBySourceId(sourceId);
	// if (node != null) {
	// AbnormalParam param = new AbnormalParam();
	// param.setNodeid(node.getId());
	// if (state > 0) {
	// param.setNumber(1);
	// } else {
	// param.setNumber(0);
	// }
	// param.setState(state);
	// try {
	// testAbnormal(param);
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// }
	// }
	//
	// @Override
	// public void testAbnormal(AbnormalParam param) throws Exception {
	// TopographyNode node = iTopographyNodeDao.findById(param.getNodeid() !=
	// null ? param.getNodeid() : "").orElse(null);
	// TopographyLine link = iTopographyLineDao.findById(param.getLinkid() !=
	// null ? param.getLinkid() : "").orElse(null);
	// String treeid = null;
	// int type = 0;
	// if (node != null) {
	// node.setState(param.getState());
	// node.setNumber(param.getNumber());
	// treeid = node.getTreeid();
	// iTopographyNodeDao.save(node);
	// type = node.getType();
	// }
	// if (link != null) {
	// link.setState(param.getState());
	// link.setNumber(param.getNumber());
	// treeid = link.getTreeid();
	// iTopographyLineDao.save(link);
	// type = link.getType();
	// }
	// //添加点详情
	// String nodeDetailItem = param.getNodeDetailItem();
	// if (nodeDetailItem != null && !"".equals(nodeDetailItem)) {
	// int state = param.getState();
	// String nodeid = param.getNodeid() != null ? param.getNodeid() : "";
	// TopographyNodeDetail nodeDetail =
	// iTopographyNodeDetailDao.findByNodeid(param.getNodeid() != null ?
	// param.getNodeid() : "");
	// if (nodeDetail == null) {
	// nodeDetail = new TopographyNodeDetail();
	// nodeDetail.setNodeid(nodeid);
	// nodeDetail = iTopographyNodeDetailDao.save(nodeDetail);
	// }
	// String detail = nodeDetail.getNodeDetail();
	// List<TopoNodeDetailParam> detailList = JSONArray.parseArray(detail,
	// TopoNodeDetailParam.class);
	// if (detailList == null) {
	// detailList = new ArrayList<>();
	// }
	// TopoNodeDetailParam newExcept = new TopoNodeDetailParam(nodeDetailItem,
	// "异常");
	// if (state > 0 && !detailList.contains(newExcept)) { //异常，添加点详情信息
	// detailList.add(newExcept);
	// nodeDetail.setNodeDetail(detailList.toString());
	// } else {
	// List<TopoNodeDetailParam> newList = detailList.stream().filter(n ->
	// !nodeDetailItem.equals(n.getName())).collect(Collectors.toList());
	// nodeDetail.setNodeDetail(newList.toString());
	// }
	// iTopographyNodeDetailDao.save(nodeDetail);
	// }
	// if (treeid != null && type == 1) {
	// webSocketServer.sendMessage(treeid, "topography");
	// }
	// if (treeid != null && type == 2) {
	// webSocketServer.sendMessage(treeid, "pams");
	// }
	// if (treeid != null && type == 3) {
	// webSocketServer.sendMessage(treeid, "donghuan");
	// }
	// if (type == 4) {
	// webSocketServer.sendMessage("refresh", "shebei");
	// }
	// }
	//
	// @Override
	// public void sendAbnormalByType(String sourceId, int state, int type,
	// String nodeDetailItem) {
	// TopographyNode node = iTopographyNodeDao.findBySourceIdAndType(sourceId,
	// type);
	// if (node != null) {
	// AbnormalParam param = new AbnormalParam();
	// param.setNodeid(node.getId());
	// Integer number = node.getNumber();
	// if (state > 0) {
	// number = number != null ? number + 1 : 1;
	// param.setNumber(number);
	//
	// } else {
	// number -= 1;
	// param.setNumber(number < 0 ? 0 : number);
	// if (number > 0) {
	// state = 2;
	// }
	// }
	// param.setState(state);
	// if (nodeDetailItem != null) {
	// param.setNodeDetailItem(nodeDetailItem);
	// }
	// try {
	// testAbnormal(param);
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// }
	// }
	//
	// @Override
	// public void delWebTree(String treeid) {
	// List<TopographyTree> trees =
	// iTopographyTreeDao.findByType(1).stream().filter(tree ->
	// Arrays.asList(tree.getTreeCode().split("\\*")).contains(treeid)).collect(Collectors.toList());
	// iTopographyTreeDao.deleteAll(trees);
	// }
	//
	// @Override
	// public void addWebTree(TopographyTreeDTO tree) {
	// TopographyTree t = new TopographyTree();
	// t.setId(UUID.randomUUID().toString().replaceAll("-", ""));
	// t.setCode(Math.abs(new Random().nextInt()) + "");
	// t.setParentCode(tree.getParent());
	// t.setName(tree.getName());
	// t.setOrgCode(tree.getOrgCode());
	// if (tree.getParent() != null) {
	// TopographyTree parent =
	// iTopographyTreeDao.findByCodeAndType(tree.getParent(), 1);
	// t.setTreeCode(parent.getTreeCode() + "*" + t.getCode());
	// } else {
	// t.setTreeCode(t.getCode());
	// }
	// t.setType(1);
	// iTopographyTreeDao.save(t);
	// }

	/**
	 * 
	 * <pre>
	 * 获取节点详情
	 * </pre>
	 *
	 * @param id
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<Map> getNodeDetail(String id)
	{
		TopographyNodeDTO node = topographyNodeService.queryById(id);
		TopographyNodeDetailDTO detail = topographyNodeDetailService.queryByNodeid(id);
		List<Map> list = new ArrayList<>();
		if (detail != null)
		{
			list = JSON.parseArray(detail.getNodeDetail(), Map.class);
//            for (Map map : list) {
//                if (map.get("name").equals("监测状态") || map.get("name").equals("健康状态")) {
//                    if (node.getState() == 0) {
//                        map.put("value", "正常");
//                    }
//                }
//            }
            return list;
		}
		return list;
	}

	// @Override
	// public List<Map> getDeviceNodes(String orgcode) {
	// List<TopographyNode> nodes =
	// iTopographyNodeDao.findByOrgCodeAndType(orgcode, 4);
	// List<Map> results = new ArrayList<>();
	// for (TopographyNode node : nodes) {
	// TopographyNodeDTO nodeDTO = convert(node);
	// Map map = JSON.parseObject(JSON.toJSONString(nodeDTO), Map.class);
	// try {
	// Map ports = JSON.parseObject(node.getPorts(), Map.class);
	// map.putAll(ports);
	// } catch (Exception e) {
	// }
	// results.add(map);
	// }
	// return results;
	// }
	//
	//
	// @Override
	// public List<TopographyLineDTO> getDeviceLinks(String orgcode) {
	// return getLinks(orgcode,null, 4);
	// }
	//
	// @Override
	// public void sendPMTSAbnormal(String fromSourceId, String toSourceId,
	// String groupName, Long treeId, int state) {
	// String treeIdStr = String.valueOf(treeId);
	//
	// TopographyNode group =
	// iTopographyNodeDao.findByTextAndTreeidAndIsGroup(groupName, treeIdStr,
	// true);
	// String groupKey = group.getKey();
	//
	// TopographyNode fromNode =
	// iTopographyNodeDao.findBySourceIdAndTreeidAndGroup(fromSourceId,
	// treeIdStr, groupKey);
	// TopographyNode toNode =
	// iTopographyNodeDao.findBySourceIdAndTreeidAndGroup(toSourceId, treeIdStr,
	// groupKey);
	// if (fromNode != null && toNode != null) {
	// TopographyLine line =
	// iTopographyLineDao.findByFromAndToAndTreeid(fromNode.getKey(),
	// toNode.getKey(), treeIdStr);
	// if (line != null) {
	// line.setState(state);
	// iTopographyLineDao.save(line);
	//
	// try {
	// webSocketServer.sendMessage(line.getTreeid(), "pams");
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// }
	// }
	//
	// }
	//
	// /**
	// * 去除字符串前n个字符
	// * @param origin 要操作的字符串
	// * @param count 去掉字符串的数量
	// * @return
	// */
	// public static String truncateHeadString(String origin, int count) {
	// if (origin == null || origin.length() < count) {
	// return null;
	// }
	// char[] arr = origin.toCharArray();
	// char[] ret = new char[arr.length - count];
	// for (int i = 0; i < ret.length; i++) {
	// ret[i] = arr[i + count];
	// }
	// return String.copyValueOf(ret);
	// }
}
