package org.springblade.third.iotdevice.service.impl;

import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.utils.ByteConvert;
import org.springblade.common.utils.JsonUtils;
import org.springblade.community.feign.IResidentialClient;
import org.springblade.device.entity.IotAlarm;
import org.springblade.device.entity.IotDevice;
import org.springblade.device.entity.IotDeviceHeartbeat;
import org.springblade.device.feign.*;
import org.springblade.device.vo.IotAlarmVO;
import org.springblade.sms.service.IPepNoticeService;
import org.springblade.system.expand.feign.IOrgPositionClient;
import org.springblade.system.user.feign.IUserClient;
import org.springblade.third.iotdevice.entity.SingleHeartBeat;
import org.springblade.third.iotdevice.service.IDataReportStrategy;
import org.springblade.third.iotdevice.util.RedisUtil;
import org.springblade.third.iotdevice.util.SendMessageBuildUtil;
import org.springblade.third.sms.dto.PepSmsSendDto;
import org.springblade.third.sms.dto.PepVoiceSendDto;
import org.springblade.workorder.deviceorder.entity.DeviceOrder;
import org.springblade.workorder.deviceorder.feign.IDeviceOrderClient;
import org.springframework.data.redis.core.RedisTemplate;
import sun.misc.BASE64Decoder;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author lidexi
 * @date 2021/5/27 18:02
 * aep平台数据上报-没有profile的处理策略
 */
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
public class NoProfileDataReportStrategy implements IDataReportStrategy {

	private IIotDeviceClient iotDeviceClient;
	private IIotDeviceHeartbeatClient iotDeviceHeartbeatClient;
	private IIotAlarmClient iotAlarmClient;
	private IDeviceOrderClient deviceOrderClient;
	private OrderGenerateUtilService orderGenerateUtilService;
	private  IResidentialClient residentialClient;
	private  IIotAlarmGroupClient iotAlarmGroupClient;
	private  IIotAlarmGroupUserClient iotAlarmGroupUserClient;
	private IPepNoticeService pepNoticeService;
	private IUserClient userClient;
	private RedisTemplate<String,String> redisTemplate;
	private IOrgPositionClient orgPositionClient;


	@Override
	public void dataReport(Map<String, Object> map) {
		log.error("dataReport --> " + JSONUtil.toJsonStr(map));

		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		//判断是告警报告还是心跳报告： 02 心跳报告 03 告警上报
		Map payload = (Map) map.get("payload");
		String appData = payload.get("APPdata").toString();
		String appDataDecode = null;
		try {
			appDataDecode = new String((new BASE64Decoder()).decodeBuffer(appData));
		} catch (IOException e) {
			e.printStackTrace();
		}
		//设备状态位
		char[] status = appDataDecode.substring(10, 14).toCharArray();
		String heartOrAlarm = appDataDecode.substring(6, 8);
		String sensorParam = appDataDecode.substring(14, 22);
		char[] sensorParamToChar = sensorParam.toCharArray();
		//小端模式转化为大端模式
		ByteConvert.swap(sensorParamToChar);
		ByteConvert.swap(status);
		//设备状态位（二进制）
		String statusBinary = ByteConvert.parseHexStr2Byte(new String(status));

		//温度和浓度
		String temperatureAndConcentration = new String(sensorParamToChar);
		String temperature = temperatureAndConcentration.substring(0, 4);
		Integer deviceTemperature = Integer.parseInt(temperature, 16);
		String concentration = temperatureAndConcentration.substring(4, 8);
		Integer deviceConcentration = Integer.parseInt(concentration, 16);
		//电池电量
		String battery = appDataDecode.substring(22, 26);
		Integer deviceBattery = Integer.parseInt(battery, 16);

		String imei = map.get("IMEI").toString();
		IotDevice searchDevice = new IotDevice();
		searchDevice.setImei(imei);
		IotDevice smartDevice = iotDeviceClient.detail(searchDevice);
		sf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
		String timestamp = map.get("timestamp").toString();
		Date date = new Date(Long.valueOf(timestamp));
		if (heartOrAlarm.equals("02")) {//心跳报告
//			smartDevice.setBattery(deviceBattery > 3200 ? String.valueOf(100) : String.valueOf(deviceBattery / 3200));

			//修改设备
			iotDeviceClient.update(smartDevice);
			//保存心跳数据
			List<SingleHeartBeat> heartBeats = new ArrayList<>();

			SingleHeartBeat batteryHeartBeat = new SingleHeartBeat();
			batteryHeartBeat.setLabel("电池电量")
				.setName("battery").
				setValue(deviceBattery > 3000 ? String.valueOf(100) : String.valueOf(deviceBattery / 3000));

			SingleHeartBeat concentrationHeartBeat = new SingleHeartBeat();
			concentrationHeartBeat.setLabel("浓度").setName("concentration").setValue(deviceConcentration.toString());

			SingleHeartBeat temperatureHeartBeat = new SingleHeartBeat();
			temperatureHeartBeat.setLabel("温度").setName("temperature").setValue(deviceTemperature.toString());

			heartBeats.add(batteryHeartBeat);
			heartBeats.add(concentrationHeartBeat);
			heartBeats.add(temperatureHeartBeat);
			IotDeviceHeartbeat deviceHeartbeat = new IotDeviceHeartbeat();

			deviceHeartbeat.setDeviceName(smartDevice.getDeviceName());
			deviceHeartbeat.setDeviceId(smartDevice.getId());
			deviceHeartbeat.setPlatform("aep");
			deviceHeartbeat.setData(JsonUtils.listToString(heartBeats));
			iotDeviceHeartbeatClient.save(deviceHeartbeat);

		} else if (heartOrAlarm.equals("03")) {//告警上报

			IotAlarm alarm = new IotAlarm();
			alarm.setDeviceId(smartDevice.getImei());
			alarm.setIsAlarm(1);
			alarm.setDeviceName(smartDevice.getDeviceName());
			alarm.setRecordTime(sf.format(date));
			alarm.setMonitorValue(deviceConcentration.toString());
			alarm.setDeviceType(smartDevice.getDeviceType());
			alarm.setAlarmType(1);
			alarm.setTenantId(smartDevice.getTenantId());
			StringBuffer sb = new StringBuffer();
			if (statusBinary.substring(7, 8).equals("1")) {
				sb.append("烟雾报警");
			}
			if (statusBinary.substring(6, 7).equals("1")) {
				sb.append("电池低压");
			}
			if (statusBinary.substring(5, 6).equals("1")) {
				sb.append("温度报警");
			}
			if (statusBinary.substring(4, 5).equals("1")) {
				sb.append("故障报警");
			}

			if (statusBinary.substring(3, 4).equals("1")) {
				sb.append("按键测试报警");
			}
			if (sb.length() == 0) {
				sb.append("正常告警");
				return ;
			}
			alarm.setAlarmDesc(sb.toString());
			alarm.setOrgPosition(smartDevice.getOrgPosition());
			alarm.setName(sb.toString());
			IotAlarm selectAlarm = new IotAlarm();
			selectAlarm.setAlarmDesc(alarm.getAlarmDesc());
			selectAlarm.setDeviceId(alarm.getDeviceId());

			//查询出与该告警记录一样的告警记录

			List<IotAlarmVO> alarms = iotAlarmClient.list(selectAlarm);
			System.out.println(alarms);
			if (alarms.size() > 0) {
				IotAlarm alarm1 = alarms.get(0);
				if (alarm1.getOrderId() == null || alarm1.getOrderId().equals("")) {//未生成工单
					alarm1.setAlarmTimes(alarm1.getAlarmTimes() + 1);

					try {
						alarm1.setLastNoticeDate(sf.parse(alarm.getRecordTime()));
					} catch (ParseException e) {
						e.printStackTrace();
					}

					iotAlarmClient.update(alarm1);
					//自动生成工单
					orderGenerateUtilService.deviceAlarmOrderGenerate(alarm,smartDevice);

					//构建短信发送对象
					List<PepSmsSendDto> pepSmsSendDtos = SendMessageBuildUtil.buildIotSmsSendDto(alarm1,iotDeviceClient
						,residentialClient,iotAlarmGroupClient,iotAlarmGroupUserClient);
					pepSmsSendDtos.stream().forEach(pepSmsSendDto -> this.pepNoticeService.sendSms(pepSmsSendDto));

					//构建语音发送对象
					List<PepVoiceSendDto> pepVoiceSendDtos = SendMessageBuildUtil.buildIotVoiceSendDto(alarm1,iotDeviceClient
						,residentialClient,iotAlarmGroupClient,iotAlarmGroupUserClient);
					pepVoiceSendDtos.stream().forEach(pepVoiceSendDto -> this.pepNoticeService.sendVoice(pepVoiceSendDto));
					return ;
				} else if (alarm1.getOrderId() != null) {//已生成工单
					DeviceOrder searchOrder = new DeviceOrder();
					searchOrder.setId(Long.valueOf(alarm1.getOrderId()));
					DeviceOrder deviceJob = deviceOrderClient.detail(searchOrder);
					if (deviceJob != null && deviceJob.getJobStatus() == 2) {//工单已完成

						boolean save = iotAlarmClient.save(alarm);//保存记录
						if (save) {
							//自动生成工单
							orderGenerateUtilService.deviceAlarmOrderGenerate(alarm,smartDevice);
							//通知后台管理账号
							RedisUtil.saveAlarmToRedis(alarm,alarm.getOrgPosition(), alarm.getTenantId(),userClient,
								redisTemplate,orgPositionClient);
						}
//						sendSms(alarm);//新增告警记录时发送短信
						//构建短信发送对象
						List<PepSmsSendDto> pepSmsSendDtos = SendMessageBuildUtil.buildIotSmsSendDto(alarm,iotDeviceClient
							,residentialClient,iotAlarmGroupClient,iotAlarmGroupUserClient);
						pepSmsSendDtos.stream().forEach(pepSmsSendDto -> this.pepNoticeService.sendSms(pepSmsSendDto));

						//构建语音发送对象
						List<PepVoiceSendDto> pepVoiceSendDtos = SendMessageBuildUtil.buildIotVoiceSendDto(alarm,iotDeviceClient
							,residentialClient,iotAlarmGroupClient,iotAlarmGroupUserClient);
						pepVoiceSendDtos.stream().forEach(pepVoiceSendDto -> this.pepNoticeService.sendVoice(pepVoiceSendDto));
						return ;
					} else if (deviceJob != null && deviceJob.getJobStatus() == 1) {//未完成
						alarm1.setAlarmTimes(alarm1.getAlarmTimes() + 1);
						try {
							alarm1.setLastNoticeDate(sf.parse(alarm.getRecordTime()));
						} catch (ParseException e) {
							e.printStackTrace();
						}
						//构建短信发送对象
						List<PepSmsSendDto> pepSmsSendDtos = SendMessageBuildUtil.buildIotSmsSendDto(alarm1,iotDeviceClient
							,residentialClient,iotAlarmGroupClient,iotAlarmGroupUserClient);
						pepSmsSendDtos.stream().forEach(pepSmsSendDto -> this.pepNoticeService.sendSms(pepSmsSendDto));

						//构建语音发送对象
						List<PepVoiceSendDto> pepVoiceSendDtos = SendMessageBuildUtil.buildIotVoiceSendDto(alarm1,iotDeviceClient
							,residentialClient,iotAlarmGroupClient,iotAlarmGroupUserClient);
						pepVoiceSendDtos.stream().forEach(pepVoiceSendDto -> this.pepNoticeService.sendVoice(pepVoiceSendDto));
						return ;
					}
				}
			} else {
				alarm.setAlarmTimes(1);

				iotAlarmClient.save(alarm);
				//自动生成工单
				orderGenerateUtilService.deviceAlarmOrderGenerate(alarm,smartDevice);
				//通知后台管理账号
				RedisUtil.saveAlarmToRedis(alarm,alarm.getOrgPosition(), alarm.getTenantId(),userClient,
					redisTemplate,orgPositionClient);
//				sendSms(alarm);
				//构建短信发送对象
				List<PepSmsSendDto> pepSmsSendDtos = SendMessageBuildUtil.buildIotSmsSendDto(alarm,iotDeviceClient
					,residentialClient,iotAlarmGroupClient,iotAlarmGroupUserClient);
				pepSmsSendDtos.stream().forEach(pepSmsSendDto -> this.pepNoticeService.sendSms(pepSmsSendDto));

				//构建语音发送对象
				List<PepVoiceSendDto> pepVoiceSendDtos = SendMessageBuildUtil.buildIotVoiceSendDto(alarm,iotDeviceClient
					,residentialClient,iotAlarmGroupClient,iotAlarmGroupUserClient);
				pepVoiceSendDtos.stream().forEach(pepVoiceSendDto -> this.pepNoticeService.sendVoice(pepVoiceSendDto));
			}
		}


	}
}
