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.alarm.alarmgroup.entity.AlarmGroup;
import org.springblade.alarm.alarmgroup.service.IAlarmGroupService;
import org.springblade.alarm.alarmgroupuser.entity.AlarmGroupUser;
import org.springblade.alarm.alarmgroupuser.service.IAlarmGroupUserService;
import org.springblade.community.residential.entity.Residential;
import org.springblade.community.residential.service.IResidentialService;
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.modules.system.entity.DictBiz;
import org.springblade.modules.system.service.IDictBizService;
import org.springblade.openinterface.dto.IotSmsVoiceDto;
import org.springblade.smartapplication.smartsmoke.entity.SmartDevice;
import org.springblade.smartapplication.smartsmoke.service.ISmartDeviceService;
import org.springblade.utils.AlarmSendSmsAndVoiceUtil;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
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 org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.format.DateTimeFormatter;
import java.util.*;

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


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

	@PostMapping("/oneKeyAlarm/dataReport")
	public R iotDeviceDataReport(@RequestBody Map<String, Object> map) throws IOException {
		log.error("dataReport --> " + JSONUtil.toJsonStr(map));
		logger.info("oneKeyAlarm/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);
			}
		}
		/*if("v1/up/ad19prof".equals(topic)){
			Map payload = (Map)map.get("payload");
			Map serviceData = (Map)payload.get("serviceData");
			String imei = map.get("IMEI").toString();
			SmartDevice smartDevice = smartDeviceService.getBaseMapper().selectOne(new QueryWrapper<>(new SmartDevice()).lambda().eq(SmartDevice::getImei, imei));
			DictBiz dictBiz = dictBizService.getBaseMapper().selectOne(new QueryWrapper<>(new DictBiz()).lambda().eq(DictBiz::getCode, "onekey_alarm_type").eq(DictBiz::getDictKey, serviceData.get("alarmcode")));


			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//			sf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
			String timestamp = map.get("timestamp").toString();
			Date date = new Date(Long.valueOf(timestamp));

			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(dictBiz.getDictValue());
			alarm.setName(dictBiz.getDictValue());
			alarmService.save(alarm);

//			AlarmSendSmsAndVoiceUtil alarmSendSmsAndVoiceUtil = new AlarmSendSmsAndVoiceUtil(redisTemplate, smartDeviceService, residentialService, alarmGroupService, alarmGroupUserService);
//			发送语音
//			alarmSendSmsAndVoiceUtil.sendVoice(alarm);//已过时
//			发送短信
//			alarmSendSmsAndVoiceUtil.sendSms(alarm);//已过时
			EventBusFactorys eventBusFactorys = EventBusFactorys.get();
			eventBusFactorys.getController("alarmSendSmsSubscriber").post(alarm);//异步发送短信
			eventBusFactorys.getController("alarmSendVoiceSubscriber").post(alarm);//异步发送语音
		}*/
		return R.status(true);
	}

	@PostMapping("/oneKeyAlarm/deviceOnlineOfflineReport")
	public R iotDeviceDataReportTupUnion(@RequestBody Map<String, Object> map) {
		log.error("deviceOnlineOfflineReport --> " + JSONUtil.toJsonStr(map));
		logger.info("oneKeyAlarm/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);
	}

	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 "991":
				alarmDesc = "燃气报警";
				break;
			case "122":
				alarmDesc = "紧急报警";
				break;
		}
		return alarmDesc;
	}




}
