package com.yeejoin.amos.boot.module.ccs.biz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yeejoin.amos.boot.module.ccs.api.dto.FireStationInfoDto;
import com.yeejoin.amos.boot.module.ccs.api.entity.FireEquipmentSignalLog;
import com.yeejoin.amos.boot.module.ccs.api.mapper.FireEquipmentSignalLogMapper;
import com.yeejoin.amos.boot.module.ccs.api.service.IFireStationInfoService;
import com.yeejoin.amos.boot.module.ccs.api.service.MqttReceiveService;
import com.yeejoin.amos.boot.module.ccs.api.vo.AlarmEventLogVO;
import com.yeejoin.amos.boot.module.ccs.api.vo.QuestionVO;
import com.yeejoin.amos.boot.module.ccs.api.vo.RawDataVO;
import com.yeejoin.amos.boot.module.ccs.api.vo.ReceiveDataVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MqttReceiveServiceImpl implements MqttReceiveService {


    private static Boolean bool = Boolean.FALSE;

    @Autowired
    private FireEquipmentSignalLogServiceImpl fireEquipmentSignalLogServiceImpl;

    @Autowired
    private IFireStationInfoService fireStationInfoService;

    @Autowired
    private FireEquipmentSignalLogMapper fireEquipmentSignalLogMapper;

    @Autowired
    protected EmqKeeper emqKeeper;

    public static final String EMERGENCY_ALARM_DATA_REFRESH = "emergency/alarm/data/refresh";

    //TODO 逻辑待补充
    @Override
    public void handlerMqttAlarmMessage(String topic, String message) {
        Date now = DateUtil.date();
        ReceiveDataVO receiveData = new ReceiveDataVO();
        try {
            // 将JSON字符串转换成实体类型
            receiveData = JSONUtil.toBean(message, ReceiveDataVO.class);
        } catch (Exception e) {
            log.error("接受消息解析失败，{}", e.getMessage());
            throw new BadRequest("接受消息解析失败");
        }
        if (ObjectUtil.isNotEmpty(receiveData) && StrUtil.isNotEmpty(receiveData.getActive()) &&
                "insert".equals(receiveData.getActive()) && ObjectUtil.isNotEmpty(receiveData.getAlarmEventLog())) {
            AlarmEventLogVO alarmEventLog = receiveData.getAlarmEventLog();

            if (StrUtil.isNotEmpty(alarmEventLog.getObjectType()) && "equipment".equals(alarmEventLog.getObjectType()) &&
                    StrUtil.isNotEmpty(alarmEventLog.getObjectIndexType()) && "FIREALARM".equals(alarmEventLog.getObjectIndexType()) &&
            StrUtil.isNotEmpty(alarmEventLog.getOrgCode())) {
                FireEquipmentSignalLog fireEquipmentSignalLog = new FireEquipmentSignalLog();
                fireEquipmentSignalLog.setStationCode(alarmEventLog.getCompanyCode());
                fireEquipmentSignalLog.setFireEquipmentIndexValue(alarmEventLog.getObjectIndexValue());
                fireEquipmentSignalLog.setFireEquipmentMrid(alarmEventLog.getObjectCode());
                fireEquipmentSignalLog.setFireEquipmentName(alarmEventLog.getObjectName());
                fireEquipmentSignalLog.setFireEquipmentIndexName(alarmEventLog.getObjectIndexName());
                fireEquipmentSignalLog.setFireEquipmentIndexKey(alarmEventLog.getObjectIndexKey());
                fireEquipmentSignalLog.setFireBuildingMrid(alarmEventLog.getBuildingCode());
                fireEquipmentSignalLog.setSignalType(alarmEventLog.getObjectIndexType());
                fireEquipmentSignalLog.setSignalTypeName(alarmEventLog.getObjectIndexName());
                fireEquipmentSignalLog.setAlarmReason(alarmEventLog.getQuestionReason());
                fireEquipmentSignalLog.setConfirmState("0");
                fireEquipmentSignalLog.setConfirmDate(DateUtil.parse(alarmEventLog.getAlarmTime()));
                fireEquipmentSignalLog.setSystemMrids(alarmEventLog.getSystemCode());
                fireEquipmentSignalLog.setSystemNames(alarmEventLog.getSystemName());
                fireEquipmentSignalLog.setProtectedObjectMrid(alarmEventLog.getProtectedObjectCode());
                fireEquipmentSignalLog.setProtectedObjectName(alarmEventLog.getProtectedObjectName());
                //RecoveryStatus 0-未恢复 1-已恢复    IsAlarm 0-已恢复  1-告警
                fireEquipmentSignalLog.setIsAlarm("0".equals(alarmEventLog.getRecoveryStatus()));
                fireEquipmentSignalLog.setCreateDate(now);
                fireEquipmentSignalLog.setSignalReportDate(DateUtil.today());
                fireEquipmentSignalLog.setLocation(alarmEventLog.getBuildingName());
                fireEquipmentSignalLog.setSynDate(now);
                fireEquipmentSignalLog.setSignalId(alarmEventLog.getSignalId());
                FireStationInfoDto oneByCode = fireStationInfoService.getOneByCode(alarmEventLog.getCompanyCode());
                fireEquipmentSignalLog.setStationName(oneByCode.getName());
                fireEquipmentSignalLog.setLng(oneByCode.getLng());
                fireEquipmentSignalLog.setLat(oneByCode.getLat());
                fireEquipmentSignalLogMapper.insert(fireEquipmentSignalLog);

                // 发送mqtt消息--刷新应急指挥屏数据
                HashMap<String, String> refresh = new HashMap<>();
                refresh.put("uuId", String.valueOf(System.currentTimeMillis()));
                try {
                    emqKeeper.getMqttClient().publish(EMERGENCY_ALARM_DATA_REFRESH, JSON.toJSONString(refresh).getBytes(), 0, false);
                } catch (MqttException e) {
                    e.printStackTrace();
                }
            }
        } else if (ObjectUtil.isNotEmpty(receiveData) && StrUtil.isNotEmpty(receiveData.getActive()) &&
                "update".equals(receiveData.getActive()) && ObjectUtil.isNotEmpty(receiveData.getRawData()) && StrUtil.isNotEmpty(receiveData.getRawData().getEquipmentSpecificCode())) {
            RawDataVO rawData = receiveData.getRawData();
            FireEquipmentSignalLog fireEquipmentSignalLog = new FireEquipmentSignalLog();
            fireEquipmentSignalLog.setIsAlarm(false);
            UpdateWrapper<FireEquipmentSignalLog> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(FireEquipmentSignalLog::getFireEquipmentMrid, rawData.getEquipmentSpecificCode())
                    .eq(FireEquipmentSignalLog::getFireEquipmentIndexKey, rawData.getEquipmentIndexKey());
            fireEquipmentSignalLogServiceImpl.update(fireEquipmentSignalLog, updateWrapper);

            // 发送mqtt消息--刷新应急指挥屏数据
            HashMap<String, String> refresh = new HashMap<>();
            refresh.put("uuId", String.valueOf(System.currentTimeMillis()));
            try {
                emqKeeper.getMqttClient().publish(EMERGENCY_ALARM_DATA_REFRESH, JSON.toJSONString(refresh).getBytes(), 0, false);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
        log.info(String.format("收到mqtt（警情）消息并处理完成：%s", message));
    }

    @Override
    public void handlerMqttQuestionMessage(String topic, String message) {
        Date now = DateUtil.date();
        QuestionVO questionVO = new QuestionVO();
        try {
            // 将JSON字符串转换成实体类型
            questionVO = JSONUtil.toBean(message, QuestionVO.class);
        } catch (Exception e) {
            log.error("接受消息解析失败，{}", e.getMessage());
            throw new BadRequest("接受消息解析失败");
        }
        if (ObjectUtil.isNotEmpty(questionVO) && CollUtil.isNotEmpty(questionVO.getAlarmEventLog())) {
            questionVO.getAlarmEventLog().forEach(item -> {
                if (StrUtil.isNotEmpty(item.getSignalId())) {
                    FireEquipmentSignalLog fireEquipmentSignalLog = new FireEquipmentSignalLog();
                    //只要已下发就先改为已处理
                    fireEquipmentSignalLog.setConfirmState("1");
                    UpdateWrapper<FireEquipmentSignalLog> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.lambda().eq(FireEquipmentSignalLog::getSignalId, item.getSignalId());
                    fireEquipmentSignalLogServiceImpl.update(fireEquipmentSignalLog, updateWrapper);
                }
            });
        }
        log.info(String.format("收到mqtt（问题下发消息推送）消息并处理完成：%s", message));
    }
}
