package org.springblade.openinterface.iot;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.nepxion.eventbus.annotation.EventBus;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.alarm.alarmgroup.service.IAlarmGroupService;
import org.springblade.alarm.alarmgroupuser.service.IAlarmGroupUserService;
import org.springblade.community.residential.service.IResidentialService;
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.jobs.devicejob.entity.DeviceJob;
import org.springblade.jobs.devicejob.service.IDeviceJobService;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springblade.openinterface.dto.AlarmNoticeDto;
import org.springblade.smartapplication.smartsmoke.entity.SmartDevice;
import org.springblade.smartapplication.smartsmoke.service.ISmartDeviceService;
import org.springblade.system.orgposition.entity.OrgPosition;
import org.springblade.system.orgposition.service.IOrgPositionService;
import org.springblade.utils.AlarmSendSmsAndVoiceUtil;
import org.springblade.utils.OrderGenerateUtilService;
import org.springblade.utils.SerializableUtil;
import org.springframework.data.redis.core.RedisTemplate;
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.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("openinterface/iot")
@Api(value = "物联网设备告警开放接口", tags = "开放接口")
public class IotAlarmOpenController {

	private IAlarmService iAlarmService;
	private ISmartDeviceService iSmartDeviceService;
	private IResidentialService residentialService;
	private IDeviceJobService deviceJobService;
	private RedisTemplate<String, String> redisTemplate;
	private OrderGenerateUtilService orderGenerateUtilService;
	private IOrgPositionService orgPositionService;
	private IUserService userService;
	private IAlarmGroupService alarmGroupService;
	private IAlarmGroupUserService alarmGroupUserService;

	@PostMapping("/alarm/sync")//感知平台
	public R iotAlarmSync(@RequestBody List<AlarmNoticeDto> alarmNoticeDtoList) throws ParseException {
		EventBusFactorys eventBusFactorys = EventBusFactorys.get();

		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//		List<Alarm> insertList = new ArrayList<>();
//		List<Alarm> updateList = new ArrayList<>();
		for (int i = 0; i < alarmNoticeDtoList.size(); i++) {
			AlarmNoticeDto source = alarmNoticeDtoList.get(i);
			QueryWrapper<SmartDevice> wrapper = new QueryWrapper<>();
			wrapper.eq("device_id", source.getDeviceId());
			SmartDevice smartDevice = iSmartDeviceService.getOne(wrapper);
			if (smartDevice == null) {
				return R.status(false);
			}

			Alarm target = null;
			QueryWrapper<Alarm> queryWrapper = new QueryWrapper<>();
			if (source.getAlarmId() != null) {
				queryWrapper.eq("alarm_id", source.getAlarmId());
				target = this.iAlarmService.getOne(queryWrapper);
			} else {//没有alarmId
				/**
				 * 判断是否存在同种设设备同一告警
				 * 	  1 存在
				 * 	  	判断存在的最新一条告警是否生成工单
				 * 	  		1.1 已生成工单
				 *				判断工单状态
				 *					1.1.1 已完成（2）
				 *						直接新增
				 *					1.1.2 未完成（1）
				 *						更新该存在的告警的告警次数和最新告警时间
				 * 	  		1.2 未生成工单
				 *					更新该存在的告警的告警次数和最新告警时间
				 * 	  2 不存在
				 * 	  	直接新增
				 */
				Alarm selectAlarm = new Alarm();
				selectAlarm.setAlarmDesc(source.getAlarmDesc());
				selectAlarm.setDeviceId(source.getDeviceId());
//				selectAlarm.setMonitorValue(source.getAlarmValue());

				//查询出与该告警记录一样的告警记录
				List<Alarm> alarms = iAlarmService.getBaseMapper().selectList(new QueryWrapper<>(selectAlarm).orderByDesc("record_time"));
				System.out.println(alarms);
				if (alarms.size() > 0) {
					Alarm alarm1 = alarms.get(0);
					if (alarm1.getOrderId() == null || alarm1.getOrderId().equals("")) {//未生成工单
						alarm1.setAlarmTimes(alarm1.getAlarmTimes() + 1);

						alarm1.setLastNoticeDate(sf.parse(source.getRecordTime()));
						iAlarmService.updateById(alarm1);
						continue;
					} else if (alarm1.getOrderId() != null) {//已生成工单
						DeviceJob deviceJob = deviceJobService.getById(alarm1.getOrderId());
						if (deviceJob != null && deviceJob.getJobStatus() == 2) {//工单已完成
							Alarm alarm = new Alarm();
							alarm.setRecordTime(source.getRecordTime());
							alarm.setDeviceId(source.getDeviceId());
							alarm.setAlarmDesc(source.getAlarmDesc());
							alarm.setOrgPosition(smartDevice.getOrgPosition());

							iAlarmService.save(alarm);
							//自动生成工单
							orderGenerateUtilService.deviceAlarmOrderGenerate(alarm);
							//保存告警到redis
							try {
								saveAlarmToRedis(alarm,alarm.getOrgPosition(),smartDevice.getTenantId());
							} catch (Exception e) {
								e.printStackTrace();
							}
//							new AlarmSendSmsAndVoiceUtil(redisTemplate, iSmartDeviceService, residentialService,alarmGroupService,alarmGroupUserService).sendSms(alarm);
							eventBusFactorys.getController("alarmSendSmsSubscriber").post(alarm);//发送短信
							eventBusFactorys.getController("alarmSendVoiceSubscriber").post(alarm);//发送语音
							continue;
						} else if (deviceJob != null && deviceJob.getJobStatus() == 1) {//未完成
							alarm1.setAlarmTimes(alarm1.getAlarmTimes() + 1);
							alarm1.setLastNoticeDate(sf.parse(source.getRecordTime()));
							iAlarmService.updateById(alarm1);
//							new AlarmSendSmsAndVoiceUtil(redisTemplate, iSmartDeviceService, residentialService,alarmGroupService,alarmGroupUserService).sendSms(alarm1);
							eventBusFactorys.getController("alarmSendSmsSubscriber").post(alarm1);//发送短信
							eventBusFactorys.getController("alarmSendVoiceSubscriber").post(alarm1);//发送语音
							continue;
						}
					}
				}
			}
			int flag = 1; //新增
			if (target == null) {
				target = new Alarm();
				target.setAlarmId(source.getAlarmId());
				target.setAlarmTimes(0);
				target.setRecordTime(source.getRecordTime());
			} else {
				flag = 2; //更新
//				source.setAlarmId(target.getAlarmId());
				target.setAlarmId(target.getAlarmId());
			}

//			// 获取设备所属小区
//			if (smartDevice.getResidentialId() == null) {
//				System.out.println("该设备还没绑定小区！！！！！！！！！！");
//				return R.status(false);
//			}
//			Residential residential = residentialService.getById(smartDevice.getResidentialId());
//			if (residential == null) {
//				System.out.println("找不到该设备所属的小区！！！！！！！");
//				return R.status(false);
//			}
//			target.setOrgPosition(residential.getOrgPosition());
//			target.setTenantId(residential.getTenantId());

			target.setAlarmValue(source.getAlarmValue());
			target.setMonitorValue(source.getAlarmValue());
			target.setAlarmTimes(target.getAlarmTimes() + 1);
			target.setAlarmDesc(source.getAlarmDesc());
			target.setName(source.getAlarmDesc());
			target.setLevel(source.getLevel());
			target.setDeviceId(smartDevice.getDeviceId());
			target.setDeviceName(smartDevice.getDeviceName());
			target.setDeviceType(Integer.parseInt(smartDevice.getDeviceType()));
			target.setAlarmType(Integer.valueOf(source.getType()));
			target.setLastNoticeDate(new Date());
			target.setOrgPosition(smartDevice.getOrgPosition());
			target.setTenantId(smartDevice.getTenantId());
			if (flag == 1) {

				iAlarmService.save(target);
				//自动生成工单
				orderGenerateUtilService.deviceAlarmOrderGenerate(target);
				//保存告警到redis
				try {
					saveAlarmToRedis(target,target.getOrgPosition(),smartDevice.getTenantId());
				} catch (Exception e) {
					e.printStackTrace();
				}
//				new AlarmSendSmsAndVoiceUtil(redisTemplate, iSmartDeviceService, residentialService,alarmGroupService,alarmGroupUserService).sendSms(target);
				eventBusFactorys.getController("alarmSendSmsSubscriber").post(target);//发送短信
				eventBusFactorys.getController("alarmSendVoiceSubscriber").post(target);//发送语音
			} else if (flag == 2) {
				iAlarmService.updateById(target);
//				new AlarmSendSmsAndVoiceUtil(redisTemplate, iSmartDeviceService, residentialService,alarmGroupService,alarmGroupUserService).sendSms(target);
				eventBusFactorys.getController("alarmSendSmsSubscriber").post(target);//发送短信
				eventBusFactorys.getController("alarmSendVoiceSubscriber").post(target);//发送语音
			}
//			if(flag == 1){
//				insertList.add(target);
//			}else if(flag == 2){
//				updateList.add(target);
//			}
		}
//		if(insertList.size() > 0){
//			this.iAlarmService.saveBatch(insertList);
//		}else{
//			this.iAlarmService.updateBatchById(updateList);
//		}
		return R.status(true);
	}

	private void saveAlarmToRedis(Alarm alarm,String alarmOrgPosition, String tenantId) throws Exception {

		if (alarmOrgPosition != null && alarmOrgPosition.trim() != "") {
			if (tenantId != null) {
				//查询出该租户下所有管理员账号
				List<User> users = userService.getBaseMapper().selectList(new QueryWrapper<>(new User()).lambda().eq(User::getTenantId, tenantId));
				for (int i = 0; i < users.size(); i++) {
					//当前用户
					User user = users.get(i);
					if (isHasPermission(user, alarmOrgPosition)) {//若用户有权限
						String redisKey = "ycwg:alarm:" + user.getId()+":"+alarm.getId();
						redisTemplate.opsForValue().set(redisKey, SerializableUtil.serializeToString(alarm));
					}


				}
			}
		}
	}

	/**
	 * 判断用户账号有没有权限看到该告警记录
	 *
	 * @param user
	 * @param orgPosition
	 * @return
	 */
	private boolean isHasPermission(User user, String orgPosition) {
		boolean flag = false;
		String deptId = user.getDeptId();
		String[] deptIds = deptId.split(",");
		for (int i = 0; i < deptIds.length; i++) {

			OrgPosition orgPosition1 = orgPositionService.getBaseMapper().selectOne(new QueryWrapper<>(new OrgPosition()).lambda().eq(OrgPosition::getOrgId, deptIds[i]));
			if (orgPosition1 != null){
				if(orgPosition.contains(orgPosition1.getOrgPosition())){
					flag = true;
					break;
				}
			}

		}
		return flag;
	}
}
