package org.springblade.openinterface.iot.listener;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.logger.BladeLogger;
import org.springblade.core.tool.api.R;
import org.springblade.core.util.EventBusFactorys;
import org.springblade.homecare.alarmlist.entity.Alarm;
import org.springblade.homecare.alarmlist.service.IAlarmService;
import org.springblade.smartapplication.smartsmoke.entity.SmartDevice;
import org.springblade.smartapplication.smartsmoke.service.ISmartDeviceService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * @author zwx
 * @create 2020/12/13 13:58
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("openinterface/iot/listen")
public class IotSmokeSubscribeController {


	private BladeLogger logger;
	private IAlarmService alarmService;
	private ISmartDeviceService smartDeviceService;

	/**
	 * @param map
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/smoke/dataReport")
	public R iotDeviceDataReport(@RequestBody Map<String, Object> map) throws IOException {
		log.error("dataReport --> " + JSONUtil.toJsonStr(map));
		logger.info("smoke/dataReport", JSONUtil.toJsonStr(map));
		String topic = map.get("topic").toString();
		if("v1/up/ad19prof".equals(topic)){
			String serviceId = map.get("serviceId").toString();
			switch (serviceId){
				case "DeviceStatus":
					handleDeviceStatus(map);
					break;
				case "Alarm":
					handleAlarm(map);
			}
		}
		return R.status(true);
	}

	@PostMapping("/smoke/deviceOnlineOfflineReport")
	public R iotDeviceDataReportTupUnion(@RequestBody Map<String, Object> map) {
		log.error("deviceOnlineOfflineReport --> " + JSONUtil.toJsonStr(map));
		logger.info("smoke/deviceOnlineOfflineReport", JSONUtil.toJsonStr(map));

		String deviceId = map.get("deviceId").toString();
		Integer defenseStatus = Integer.valueOf(map.get("eventType").toString());

		SmartDevice smartDevice = smartDeviceService.getOne(new QueryWrapper<>(new SmartDevice()).lambda().eq(SmartDevice::getDeviceId, deviceId));
		if(smartDevice != null){
			if(defenseStatus == 1){
				smartDevice.setDefenseStatus(defenseStatus);
			}

			if(defenseStatus == 0){
				smartDevice.setDefenseStatus(2);
			}

			smartDeviceService.updateById(smartDevice);
		}


		return R.status(true);
	}

	/**
	 * 处理设备状态/心跳
	 * {
	 * 	"upPacketSN": -1,
	 * 	"upDataSN": -1,
	 * 	"topic": "v1/up/ad19prof",
	 * 	"timestamp": "1631965923771",
	 * 	"tenantId": "2000024151",
	 * 	"serviceId": "DeviceStatus",
	 * 	"protocol": "lwm2m",
	 * 	"profile": true,
	 * 	"productId": "15047880",
	 * 	"payload": {
	 * 		"serviceId": "DeviceStatus",
	 * 		"serviceData": {
	 * 			"voltagevalue": 3003, //电压具体值 0-65535mV
	 * 			"version": "V5.2.4_NBYGB",
	 * 			"tamperstatus": 0, //防拆状态 1 或 0（1 表示打开，0 表示压下）
	 * 			"signalvalue": 15, //信号具体值
	 * 			"signal": 3, //NB 信号强度
	 * 			"nbversion": "N256Y_SW_V001.031.000 -- ",
	 * 			"lowvalue": 2680, //电压低压门阀值 0-65535mV
	 * 			"hearttime": 24,
	 * 			"devicetype": "YG", //烟感
	 * 			"deviceid": "964046369208",
	 * 			"ccid": "89861121206010677231",
	 * 			"battery": 1, //电池是否低压 1 或 0（1 表是正常，0 表示低压）
	 * 			"SINR": "10",
	 * 			"RSRP": "-91",
	 * 			"F": 100,
	 * 			"ECL": "0",
	 * 			"CellID": "198840668"
	 *                }* 	},
	 * 	"messageType": "dataReport",
	 * 	"deviceType": "",
	 * 	"deviceId": "b8b6fb2a11cd486084c38a23cfdf97eb",
	 * 	"assocAssetId": "",
	 * 	"IMSI": "undefined",
	 * 	"IMEI": "861964046369208"
	 * }
	 * @param map
	 */
	private void handleDeviceStatus(Map<String, Object> map){
		JSONObject jsonObject = JSONUtil.parseObj(map);
		String imei = jsonObject.getStr("IMEI");
		String deviceId = jsonObject.getStr("deviceId");
		JSONObject payload = jsonObject.getJSONObject("payload");
		JSONObject serviceData = payload.getJSONObject("serviceData");

		SmartDevice device = smartDeviceService.getDevice(imei, deviceId);
		if(device != null){
			Integer signal = serviceData.getInt("signal"); //信号强度
			Integer battery = serviceData.getInt("battery"); //电量，用于判断是否正常电压
			if(battery == 1){
				device.setDefenseStatus(1);
			}else{
				device.setDefenseStatus(2);
			}
			device.setSignalIntensity(signal.toString());
			smartDeviceService.updateById(device);
		}
	}

	/**
	 * 处理设备报警
	 * @param map
	 */
	private void handleAlarm(Map<String, Object> map){
		JSONObject jsonObject = JSONUtil.parseObj(map);
		String imei = jsonObject.getStr("IMEI");
		String deviceId = jsonObject.getStr("deviceId");
		JSONObject payload = jsonObject.getJSONObject("payload");
		JSONObject serviceData = payload.getJSONObject("serviceData");

		SmartDevice smartDevice = smartDeviceService.getDevice(imei, deviceId);
		if(smartDevice != null){
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String timestamp = map.get("timestamp").toString();
			Date date = new Date(Long.valueOf(timestamp));
			String alarmCode = serviceData.getStr("alarmcode");
			String alarmDesc = this.getAlarmDesc(alarmCode);
			smartDevice.setDeviceStatus(2);
			smartDeviceService.updateById(smartDevice);

			Alarm alarm = new Alarm();
			alarm.setDeviceId(smartDevice.getDeviceId());
			alarm.setIsAlarm(1);
			alarm.setDeviceName(smartDevice.getDeviceName());
			alarm.setRecordTime(sf.format(date));
			alarm.setDeviceType(Integer.valueOf(smartDevice.getDeviceType()));
			alarm.setAlarmType(1);
			alarm.setTenantId(smartDevice.getTenantId());
			alarm.setOrgPosition(smartDevice.getOrgPosition());
			alarm.setAlarmDesc(alarmDesc);
			alarm.setName(alarmDesc);
			alarmService.save(alarm);

			EventBusFactorys eventBusFactorys = EventBusFactorys.get();
			eventBusFactorys.getController("alarmSendSmsSubscriber").post(alarm);//异步发送短信
			eventBusFactorys.getController("alarmSendVoiceSubscriber").post(alarm);//异步发送语音
		}
	}

	private String getAlarmDesc(String alarmCode){
		String alarmDesc = "设备告警";
		switch (alarmCode){
			case "111":
				alarmDesc = "烟雾报警";
				break;
			case "384":
				alarmDesc = "低压报警";
				break;
			case "986":
				alarmDesc = "高温报警";
				break;
			case "963":
				alarmDesc = "防拆报警";
				break;
			case "962":
				alarmDesc = "报警恢复正常";
				break;
			case "960":
				alarmDesc = "报警测试";
				break;
			case "955":
				alarmDesc = "温度报警";
				break;
			case "954":
				alarmDesc = "温度短路";
				break;
			case "953":
				alarmDesc = "温度开路";
				break;
		}
		return alarmDesc;
	}




}
