package com.yfd.monitor.gdw2019.event.alarm;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yfd.monitor.gdw2019.bean.*;
import com.yfd.monitor.gdw2019.transmit.cmd.ISIPCommanderForPlatform;
import com.yfd.monitor.storager.IVideoManagerStorage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.sip.InvalidArgumentException;
import javax.sip.SipException;
import java.text.ParseException;
import java.util.*;

/**
 * @description: 报警事件监听
 * @data: 2021-01-20
 */

@Component
public class AlarmEventListener implements ApplicationListener<AlarmEvent> {

    private final static Logger logger = LoggerFactory.getLogger(AlarmEventListener.class);

    private static Map<String, SseEmitter> sseEmitters = new Hashtable<>();

    @Autowired
    private SubscribeHolder subscribeHolder;

    @Autowired
    private IVideoManagerStorage storager;
    @Autowired
    private ISIPCommanderForPlatform cmdforplatform;

    public void addSseEmitters(String browserId, SseEmitter sseEmitter) {
        sseEmitters.put(browserId, sseEmitter);
    }

    @Override
    public void onApplicationEvent(AlarmEvent event) {
        // 获取所用订阅
        List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true);
        if (parentPlatforms.size() == 0) return;
        ParentPlatform parentPlatform = parentPlatforms.get(0);
        SubscribeInfo subscribeinfo = subscribeHolder.getAlarmSubscribe(parentPlatform.getServerGBId());
        if (subscribeinfo == null) {
            return;
        }
        DeviceAlarm deviceAlarm = event.getAlarmInfo();
        String items = subscribeinfo.getItems();
        JSONArray jsonArray = JSON.parseArray(items);
        List<Map<String, String>> alarmitems = new ArrayList<>();
        for (Object o : jsonArray) {
            JSONObject jobj = (JSONObject) o;
            int alarmType = Integer.parseInt(jobj.getString("Type"));
            // 截取每位字节
            int videoLoss = (alarmType & 0x01) >> 0;
            int motionDetection = (alarmType & 0x02) >> 1;
            int videoMask = (alarmType & 0x04) >> 2;
            int highTemperature = (alarmType & 0x100) >> 8;
            int lowTemperature = (alarmType & 0x200) >> 9;
            int fanFailure = (alarmType & 0x400) >> 10;
            int diskFailure = (alarmType & 0x800) >> 11;
            int statusEvent = (alarmType & 0x10000) >> 16;
            if (jobj.getString("Code").equals(deviceAlarm.getDeviceId())) {//订阅了设备
                if (deviceAlarm.getAlarmMethod().equals("2")) {//报警设备报警
                    switch (deviceAlarm.getAlarmType()) {
                        case "1"://1-视频丢失报警; 第 0 位：视频丢失告警
                            if (videoLoss == 1) {
                                Map<String, String> map = new HashMap<>();
                                map.put("Code", jobj.getString("Code"));
                                map.put("Name", deviceAlarm.getAlarmDescription());
                                map.put("Type", jobj.getString("Type"));
                                map.put("StartTime", deviceAlarm.getAlarmTime());
                                alarmitems.add(map);
                            }
                            break;
                        case "4"://4-设备高温报警; 第 8 位：设备高温告警
                            if (highTemperature == 1) {
                                Map<String, String> map = new HashMap<>();
                                map.put("Code", jobj.getString("Code"));
                                map.put("Name", deviceAlarm.getAlarmDescription());
                                map.put("Type", jobj.getString("Type"));
                                map.put("StartTime", deviceAlarm.getAlarmTime());
                                alarmitems.add(map);
                            }
                            break;
                        case "5"://5-设备低温报警。 第 9 位：设备低温告警
                            if (lowTemperature == 1) {
                                Map<String, String> map = new HashMap<>();
                                map.put("Code", jobj.getString("Code"));
                                map.put("Name", deviceAlarm.getAlarmDescription());
                                map.put("Type", jobj.getString("Type"));
                                map.put("StartTime", deviceAlarm.getAlarmTime());
                                alarmitems.add(map);
                            }
                            break;

                    }
                }
                if (deviceAlarm.getAlarmMethod().equals("5")) {//5为视频报警
                    switch (deviceAlarm.getAlarmType()) {
                        case "6"://6-入侵检测报警; 第 1 位：移动侦测告警
                            if (motionDetection == 1) {
                                Map<String, String> map = new HashMap<>();
                                map.put("Code", jobj.getString("Code"));
                                map.put("Name", deviceAlarm.getAlarmDescription());
                                map.put("Type", jobj.getString("Type"));
                                map.put("StartTime", deviceAlarm.getAlarmTime());
                                alarmitems.add(map);
                            }
                            break;
                        case "11"://11-视频异常检测报警; 第 2 位：视频遮挡告警
                            if (videoMask == 1) {
                                Map<String, String> map = new HashMap<>();
                                map.put("Code", jobj.getString("Code"));
                                map.put("Name", deviceAlarm.getAlarmDescription());
                                map.put("Type", jobj.getString("Type"));
                                map.put("StartTime", deviceAlarm.getAlarmTime());
                                alarmitems.add(map);
                            }
                            break;
                        case "12"://12-快速移动报警  第 1 位：移动侦测告警
                            if (motionDetection == 1) {
                                Map<String, String> map = new HashMap<>();
                                map.put("Code", jobj.getString("Code"));
                                map.put("Name", deviceAlarm.getAlarmDescription());
                                map.put("Type", jobj.getString("Type"));
                                map.put("StartTime", deviceAlarm.getAlarmTime());
                                alarmitems.add(map);
                            }
                            break;
                    }
                }
                if (deviceAlarm.getAlarmMethod().equals("6")) {//报警设备报警
                    switch (deviceAlarm.getAlarmType()) {
                        case "1"://1-存储设备磁盘故障报警;  第 11 位：磁盘故障告警
                            if (diskFailure == 1) {
                                Map<String, String> map = new HashMap<>();
                                map.put("Code", jobj.getString("Code"));
                                map.put("Name", deviceAlarm.getAlarmDescription());
                                map.put("Type", jobj.getString("Type"));
                                map.put("StartTime", deviceAlarm.getAlarmTime());
                                alarmitems.add(map);
                            }
                            break;
                        case "2"://2-存储设备风扇故障报警。 第 10 位：风扇故障告警
                            if (fanFailure == 1) {
                                Map<String, String> map = new HashMap<>();
                                map.put("Code", jobj.getString("Code"));
                                map.put("Name", deviceAlarm.getAlarmDescription());
                                map.put("Type", jobj.getString("Type"));
                                map.put("StartTime", deviceAlarm.getAlarmTime());
                                alarmitems.add(map);
                            }
                            break;


                    }
                }
            }
        }
        if (alarmitems.size() > 0) {
            try {
                SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(subscribeinfo.getResponse());
                cmdforplatform.sendAlarmNotice(parentPlatform, alarmitems, sipTransactionInfo);
            } catch (ParseException e) {
                e.printStackTrace();
            } catch (InvalidArgumentException e) {
                e.printStackTrace();
            } catch (SipException e) {
                e.printStackTrace();
            }

        }

    }
    //2024-02-12  注释，将sse推送修改为向上级发送告警通知
//        if (logger.isDebugEnabled()) {
//            logger.debug("设备报警事件触发，deviceId：" + event.getAlarmInfo().getDeviceId() + ", "
//                    + event.getAlarmInfo().getAlarmDescription());
//        }
//        String msg = "<strong>设备编码：</strong> <i>" + event.getAlarmInfo().getDeviceId() + "</i>"
//                    + "<br><strong>报警描述：</strong> <i>" + event.getAlarmInfo().getAlarmDescription() + "</i>"
//                    + "<br><strong>报警时间：</strong> <i>" + event.getAlarmInfo().getAlarmTime() + "</i>"
//                    + "<br><strong>报警位置：</strong> <i>" + event.getAlarmInfo().getLongitude() + "</i>"
//                    + ", <i>" + event.getAlarmInfo().getLatitude() + "</i>";
//
//        for (Iterator<Map.Entry<String, SseEmitter>> it = sseEmitters.entrySet().iterator(); it.hasNext();) {
//            Map.Entry<String, SseEmitter> emitter = it.next();
//            logger.info("推送到SSE连接，浏览器ID: " + emitter.getKey());
//            try {
//                emitter.getValue().send(msg);
//            } catch (IOException | IllegalStateException e) {
//                if (logger.isDebugEnabled()) {
//                    logger.debug("SSE连接已关闭");
//                }
//                // 移除已关闭的连接
//                it.remove();
//            }
//        }
//    }
}
