package com.yeejoin.amos.api.alarm.service.impl;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.component.emq.EmqKeeper;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yeejoin.amos.api.alarm.dto.DynamicDetails;
import com.yeejoin.amos.api.alarm.dto.TabContent;
import com.yeejoin.amos.api.alarm.dto.WarningDto;
import com.yeejoin.amos.api.alarm.entity.EquipmentSpecificIndex;
import com.yeejoin.amos.api.alarm.entity.PointSystem;
import com.yeejoin.amos.api.alarm.entity2.JumpConfig;
import com.yeejoin.amos.api.alarm.entity2.KKSData;
import com.yeejoin.amos.api.alarm.entity2.StationBasic;
import com.yeejoin.amos.api.alarm.mapper.EquipmentSpecificIndexMapper;
import com.yeejoin.amos.api.alarm.mapper.PointSystemMapper;
import com.yeejoin.amos.api.alarm.mapper2.JumpConfigMapper;
import com.yeejoin.amos.api.alarm.mapper2.KKSDataMapper;
import com.yeejoin.amos.api.alarm.mapper2.StationBasicMapper;
import com.yeejoin.amos.api.alarm.service.IPointSystemService;
import com.yeejoin.amos.api.alarm.utils.RedisUtils;

/**
 * @description:
 * @author: tw
 * @createDate: 2023/6/19
 */
@Service
public class PointSystemServiceImpl extends ServiceImpl<PointSystemMapper, PointSystem> implements IPointSystemService {

	private static final Logger logger = LogManager.getLogger(PointSystemServiceImpl.class);
	@Autowired
	PointSystemMapper pointSystemMapper;
	@Value("${power.station.url}")
	private String powerStationUrl;
	private final String TABNAME = "预警问题";

	private final String TEXT = "text";

	@Value("${power.station.warning:104/data/analysis}")
	private String STATIONWARNING;
	@Autowired
	protected EmqKeeper emqKeeper;

	@Autowired
	private JumpConfigMapper jumpConfigMapper;

	@Autowired
	private KKSDataMapper kksDataMapper;

	@Autowired
	private EquipmentSpecificIndexMapper equipmentSpecificIndexMapper;

	@Autowired
	private StationBasicMapper stationBasicMapper;

	@Autowired
	private RedisUtils redisUtil;

	@Value("${warning.redis.use:false}")
	private boolean redisUse;

	@Value("${warning.redis.limit.time:3600}")
	private long limitTime;

	@Value("${warning.SYZ:false}")
	private boolean warnSYZ;

	public String getJumpUrlByInfo(String sbbm) {
		List<JumpConfig> jumpConfigs = jumpConfigMapper.selectList(null);
		Map<String, String> collect = jumpConfigs.stream()
				.collect(Collectors.toMap(JumpConfig::getType, JumpConfig::getUrl));
		if (StringUtils.isEmpty(sbbm)) {
			return "";
		}
		if (sbbm.indexOf("BAT") != -1) {
			return collect.get("箱变");
		} else if (sbbm.indexOf("WG") != -1) {
			return collect.get("汇流箱");
		} else if (sbbm.indexOf("WC") != -1) {
			return collect.get("逆变器");
		} else if (sbbm.length() == 12 && sbbm.indexOf("MD") != -1) {
			return collect.get("风机");
		} else if (sbbm.length() > 12 && sbbm.indexOf("MD") != -1) {
			return collect.get("风机子系统");
		} else {
			return collect.get("默认");
		}
	}

	@Async("equipAsyncExecutor")
	public void sendWarningAsync(String date) {
		try {
			//logger.info("收到告警信息");
			System.out.println("收到告警信息"+LocalDateTime.now());
			com.alibaba.fastjson.JSONObject messageObj = JSON.parseObject(date);
			String address = messageObj.get("address").toString();
			String value = messageObj.get("value").toString();
			String valueLabe = messageObj.get("valueLabel").toString();
			String gatewayId = messageObj.get("gatewayId").toString();
			String isAlarm = messageObj.get("isAlarm").toString();
			this.sendWarning(address, value, valueLabe, gatewayId, isAlarm);
		} catch (Exception e) {
			//e.printStackTrace();
		}
	}

//	@PostConstruct
//	public void test() {
//		String address = "22163";
//		String value = "1.0";
//		String valueLabe = "扇区1限功率";
//		String gatewayId = "1668801435891929089";
//		String isAlarm = "1";
//		this.sendWarning(address, value, valueLabe, gatewayId, isAlarm);
//	}

	@Override
	public void sendWarning(String address, String value, String valueLabe, String gatewayId, String isAlarm) {
		// 对应 equipment库的wl_equipment_specific_index_alarm_dic表
		String[] s = { "1", "7", "9" };
		// 如果不满足择返回
		if (!Arrays.asList(s).contains(isAlarm)) {
			//System.out.println("不满足告警类型: " + isAlarm);
			return;
		}

		//System.out.println("满足告警消息address: " + address + ",gatewayId: " + gatewayId + " ,value:" + value
		//		+ " ,valueLabe: " + valueLabe + " ,isAlarm: " + isAlarm);
		//logger.info("满足告警消息address: " + address + ",gatewayId: " + gatewayId + " ,value:" + value + " ,valueLabe: "
		//		+ valueLabe + " ,isAlarm: " + isAlarm);
		// 通过测点地址获取，和对应值 获取kks
		QueryWrapper<PointSystem> pointSystemWrapper = new QueryWrapper<>();
		pointSystemWrapper.lambda().eq(PointSystem::getAddress, address);
		if (!value.equals("false") && !value.equals("true")) {
			pointSystemWrapper.lambda().eq(PointSystem::getValue, value);
		}
		pointSystemWrapper.lambda().eq(PointSystem::getGatewayId, gatewayId);
		List<PointSystem> pointSystems = pointSystemMapper.selectList(pointSystemWrapper);
		if (pointSystems == null || pointSystems.size() < 1) {
			// throw new RuntimeException("获取kks码失败: "+"address: " + address + ",gatewayId:
			// " + gatewayId + " ,value:" + value);
			//System.out.println("获取kks码失败: " + "address:" + address + ", gatewayId:" + gatewayId + " ,value:" + value);
			return;
		}

		PointSystem pointSystem = pointSystems.get(0);
//            if (pointSystem.getType().equals("遥信")){
//                return;
//            }
		// 调用获取设备相关信息
		QueryWrapper<KKSData> KKSDataWrapper = new QueryWrapper<>();
		KKSDataWrapper.lambda().eq(KKSData::getKKSBM, pointSystem.getKks());
		KKSData KKSData = kksDataMapper.selectOne(KKSDataWrapper);
		JSONObject eqdata = new JSONObject();
		if (KKSData == null) {
			// throw new RuntimeException("kks码查询热工院表不存在:" + pointSystem.getKks());
			//System.out.println("kks码查询热工院表不存在:" + pointSystem.getKks());
			return;
		}
		eqdata.put("kksms", KKSData.getKKSMS());

		QueryWrapper<StationBasic> stationWrapper = new QueryWrapper<>();
		stationWrapper.lambda().eq(StationBasic::getStationNumber, pointSystem.getStation());
		StationBasic stationBasic = stationBasicMapper.selectOne(stationWrapper);
		if (stationBasic != null) {
			eqdata.put("sourceAttribution", stationBasic.getProjectOrgCode());
			eqdata.put("sourceAttributionDesc", stationBasic.getStationName());
		} else {
			// throw new RuntimeException("获取场站失败: " + pointSystem.getStation());
			//System.out.println("获取场站失败: " + pointSystem.getStation());
			return;
		}
		try {
//			Map<String, String> maps = new HashMap<>();
//			maps.put("type", "equipinfo");
//			maps.put("kksbm", pointSystem.getKks());
//			String data = HttpContentTypeUtil.sendHttpPost(powerStationUrl, maps);
//			if (StringUtils.isEmpty(data) || !(Boolean) JSON.parseObject(data).get("success")) {
//				System.out.println("热工院返回数据: " + data);
//				logger.info("热工院返回数据: " + data);
//				throw new RuntimeException("获取设备信息失败！");
//			}
//			JSONObject json = JSON.parseObject(data);
//			JSONObject jsond = (JSONObject) json.get("dataset");
//			JSONArray list = (JSONArray) jsond.get("datas");
//			JSONObject eqdata = null;
//			if (list == null || list.isEmpty()) {
//				throw new RuntimeException("获取设备信息失败！");
//			}
//			eqdata = (JSONObject) list.get(0);
			// 组装数据，发送预警
			WarningDto warningDto = setWarningDto(pointSystem, eqdata, valueLabe);
			if (warningDto != null) {
				emqKeeper.getMqttClient().publish(STATIONWARNING, JSON.toJSONString(warningDto).getBytes(), 0, false);
				//System.out.println("发送预警成功: " + JSON.toJSONString(warningDto));
				logger.info("发送预警成功");
			}
		} catch (Exception e) {
			//e.printStackTrace();
		}
	}

	public WarningDto setWarningDto(PointSystem pointSystem, JSONObject eqdata, String valueLabe) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String time = sdf.format(new Date());
		String warningObjectCode = pointSystem.getKks();
		List<TabContent> tabContent = new ArrayList<>();
		tabContent.add(new TabContent("KKS编码", TEXT, warningObjectCode, "key1"));
		tabContent.add(new TabContent("设备名称", TEXT, eqdata.get("kksms"), "key2"));
		tabContent.add(new TabContent("告警原因", TEXT, valueLabe, "key3"));
		tabContent.add(new TabContent("发生时间", TEXT, time, "key4"));
		DynamicDetails dynamicDetails = new DynamicDetails(TABNAME, tabContent);
		List<DynamicDetails> dynamicDetailsList = new ArrayList<>();
		dynamicDetailsList.add(dynamicDetails);
		StringBuilder indexKey = new StringBuilder("WL-").append(pointSystem.getStation()).append("#")
				.append(pointSystem.getNumber()).append("#").append(pointSystem.getFunctionNum());
		if (pointSystem.getNumber() == null) {
			indexKey = new StringBuilder("WL-").append(pointSystem.getStation()).append("#")
					.append(pointSystem.getFunctionNum());
		}

		QueryWrapper<EquipmentSpecificIndex> indexWrapper = new QueryWrapper<>();
		indexWrapper.lambda().eq(EquipmentSpecificIndex::getIndexAddress, pointSystem.getAddress());
		indexWrapper.lambda().eq(EquipmentSpecificIndex::getGatewayId, pointSystem.getGatewayId());
		EquipmentSpecificIndex esi = equipmentSpecificIndexMapper.selectOne(indexWrapper);
		String indexValue = null;
		// 获取告警值
		if ("遥信".equals(pointSystem.getType())) {
			indexValue = esi.getEquipmentIndexName();
		} else if ("遥测".equals(pointSystem.getType())) {
			if ("W005".equals(pointSystem.getStation())) {
//				String json = esi.getValueEnum();
//				JSONArray arr = JSONArray.parseArray(json);
//				List<JSONObject> list = arr.toJavaList(JSONObject.class);
//				Map<String, String> map = list.stream()
//						.collect(Collectors.toMap(i -> i.getString("key"), i -> i.getString("label")));
				indexValue = valueLabe;
			} else if ("P001".equals(pointSystem.getStation())) {

			}
		} else {

		}

		// 如果是升压站
		if ("SYZ".equals(pointSystem.getNumber())) {
			// 如果开启升压站预警
			if (warnSYZ) {
				indexKey = new StringBuilder("WL-").append(pointSystem.getStation()).append("#")
						.append(pointSystem.getNumber()).append("#").append(pointSystem.getFunctionNum());
			} else {
				System.out.println("升压站预警不发送: " + warningObjectCode + " , " + indexValue);
				return null;
			}
		}

		String key = "104_warning:" + warningObjectCode + "_" + indexKey.toString() + "_" + indexValue;
		// 添加缓存机制 在有限的时间内防止一直触发
		if (redisUtil.get(key) != null && redisUse) {
			System.out.println("预警缓存存在,不触发: " + key);
			return null;
		} else {
			WarningDto WarningDto = new WarningDto(indexKey.toString(), indexValue, null,
					(String) eqdata.get("sourceAttributionDesc"), (String) eqdata.get("sourceAttribution"),
					dynamicDetailsList, warningObjectCode, time, (String) eqdata.get("kksms"), "equip",
					getJumpUrlByInfo(warningObjectCode));
			redisUtil.set(key, indexValue, limitTime);
			return WarningDto;
		}
	}

	@Async("equipAsyncExecutor")
	public void sendWarningMqttAsync(String topic, String msg) {
		try {
			JSONObject jsonObject = JSONObject.parseObject(msg);
			String group = jsonObject.getString("group");
			JSONObject valueObj = jsonObject.getJSONObject("value");
			Set<String> keys = valueObj.keySet();
			String address = null;
			String value = null;
			for (String key : keys) {
				address = key;
				value = valueObj.getString(key);
				break;
			}
			this.sendWarningMqtt(address, value, topic, group);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void sendWarningMqtt(String address, String value, String topic, String group) {

		QueryWrapper<EquipmentSpecificIndex> indexWrapper = new QueryWrapper<>();
		indexWrapper.lambda().eq(EquipmentSpecificIndex::getIndexAddress, address);
		indexWrapper.lambda().eq(EquipmentSpecificIndex::getTopic, topic);
		indexWrapper.lambda().eq(EquipmentSpecificIndex::getGroup, group);
		EquipmentSpecificIndex esi = equipmentSpecificIndexMapper.selectOne(indexWrapper);
		
		String isAlarm = String.valueOf(esi.getIsAlarm().intValue());
		// 对应 equipment库的wl_equipment_specific_index_alarm_dic表
		String[] s = { "1", "7", "9" };
		// 如果不满足择返回
		if (!Arrays.asList(s).contains(isAlarm)) {
			System.out.println("不满足告警类型: " + isAlarm);
			return;
		}

		System.out.println("满足告警消息address: " + address + ",topic: " + topic + " ,value:" + value
				+ " ,group: " + group + " ,isAlarm: " + isAlarm);
		logger.info("满足告警消息address: " + address + ",topic: " + topic + " ,value:" + value
				+ " ,group: " + group + " ,isAlarm: " + isAlarm);
		
		LambdaQueryWrapper<PointSystem> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(PointSystem::getTopic, topic);
		wrapper.eq(PointSystem::getGroup, group);
		wrapper.eq(PointSystem::getAddress, address);
		PointSystem pointSystem = pointSystemMapper.selectOne(wrapper);
		
		String valueLabe=null;
		JSONObject eqdata = new JSONObject();
		
		// 调用获取设备相关信息
		QueryWrapper<KKSData> KKSDataWrapper = new QueryWrapper<>();
		KKSDataWrapper.lambda().eq(KKSData::getKKSBM, pointSystem.getKks());
		KKSData KKSData = kksDataMapper.selectOne(KKSDataWrapper);
		if (KKSData == null) {
			// throw new RuntimeException("kks码查询热工院表不存在:" + pointSystem.getKks());
			System.out.println("kks码查询热工院表不存在:" + pointSystem.getKks());
			return;
		}
		eqdata.put("kksms", KKSData.getKKSMS());
		
		QueryWrapper<StationBasic> stationWrapper = new QueryWrapper<>();
		stationWrapper.lambda().eq(StationBasic::getStationNumber, pointSystem.getStation());
		StationBasic stationBasic = stationBasicMapper.selectOne(stationWrapper);
		if (stationBasic != null) {
			eqdata.put("sourceAttribution", stationBasic.getProjectOrgCode());
			eqdata.put("sourceAttributionDesc", stationBasic.getStationName());
		} else {
			// throw new RuntimeException("获取场站失败: " + pointSystem.getStation());
			System.out.println("获取场站失败: " + pointSystem.getStation());
			return;
		}
		
		try {
			// 组装数据，发送预警
			WarningDto warningDto = setWarningDto(pointSystem, eqdata, valueLabe);
			if (warningDto != null) {
				emqKeeper.getMqttClient().publish(STATIONWARNING, JSON.toJSONString(warningDto).getBytes(), 0, false);
				System.out.println("发送预警成功: " + JSON.toJSONString(warningDto));
				// logger.info("发送预警成功: " + JSON.toJSONString(warningDto));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}