package com.mortals.xhx.base.framework.listener;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.model.BizLogPdu;
import com.mortals.framework.model.ErrorLogPdu;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.IMessageProduceService;
import com.mortals.xhx.common.code.*;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.pdu.RespData;
import com.mortals.xhx.common.pdu.sms.SmsSetPdu;
import com.mortals.xhx.feign.sms.ISmsSetFeign;
import com.mortals.xhx.module.alarm.model.AlarmConfigEntity;
import com.mortals.xhx.module.alarm.model.AlarmConfigQuery;
import com.mortals.xhx.module.alarm.model.AlarmSmsSendEntity;
import com.mortals.xhx.module.alarm.service.AlarmConfigService;
import com.mortals.xhx.module.alarm.service.AlarmSmsSendService;
import com.mortals.xhx.module.device.model.DeviceAlarmInfoEntity;
import com.mortals.xhx.module.device.model.DeviceAlarmInfoQuery;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.service.DeviceAlarmInfoService;
import com.mortals.xhx.module.device.service.DeviceService;
import com.mortals.xhx.module.platform.model.PlatformEntity;
import com.mortals.xhx.module.platform.service.PlatformService;
import com.mortals.xhx.module.product.model.ProductEntity;
import com.mortals.xhx.module.product.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.mortals.xhx.common.key.RedisKey.KEY_DEVICE_ONLINE_CACHE;

/**
 * 离线通知
 *
 * @author: zxfei
 * @date: 2022/6/22 16:40
 * @description:
 **/
@Slf4j
@Component
public class CustomerKeyExpirationListener implements MessageListener {

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private ProductService productService;
    @Autowired
    private PlatformService platformService;
    @Autowired
    private AlarmConfigService alarmConfigService;
    @Autowired
    private DeviceAlarmInfoService deviceAlarmInfoService;
    @Autowired
    private AlarmSmsSendService alarmSmsSendService;
    @Autowired
    private ISmsSetFeign smsSetFeign;
    @Autowired
    private IMessageProduceService messageProducer;
    @Autowired
    private ICacheService cacheService;

    @Override
    public void onMessage(Message message, byte[] bytes) {
        String key = message.toString();
        //解决分布式系统 重复获取广播消息

        String subStr = StrUtil.removePrefix(key, KEY_DEVICE_ONLINE_CACHE);
        if (!subStr.equals(key)) {
            boolean setnx = cacheService.setnx(subStr+"#lock", 1, 5);
            if (setnx) {
                DeviceEntity deviceEntity = deviceService.getExtCache(subStr);
                if (!ObjectUtils.isEmpty(deviceEntity)) {
                    if (deviceEntity.getDeviceStatus() == DeviceStatusEnum.在线.getValue()) {
            /*            deviceEntity.setOfflineTime(new Date());
                        deviceEntity.setDeviceStatus(DeviceStatusEnum.离线.getValue());

                        DeviceEntity entity = new DeviceEntity();
                        entity.setOfflineTime(new Date());
                        entity.setUpdateTime(new Date());
                        entity.setDeviceStatus(DeviceStatusEnum.离线.getValue());
                        DeviceEntity condition = new DeviceEntity();
                        condition.setId(deviceEntity.getId());
                        deviceService.getDeviceDao().update(entity, condition);
                        deviceService.putCache(deviceEntity.getId().toString(), deviceEntity);*/

                        DeviceEntity condition = new DeviceEntity();
                        condition.setId(deviceEntity.getId());
                        condition.setOfflineTime(new Date());
                        condition.setDeviceStatus(DeviceStatusEnum.离线.getValue());

                        cacheService.lpush(RedisKey.KEY_DEVICE_UPDATE_QUEUE,condition);

                        log.info("deviceCode:{}，deviceName:{}==>离线", deviceEntity.getDeviceCode(), deviceEntity.getDeviceName());
                        // deviceService.update(deviceEntity);
                        PlatformEntity platformEntity = platformService.getCache(deviceEntity.getPlatformId().toString());
                        ProductEntity productEntity = productService.getCache(deviceEntity.getProductId().toString());
                        if (!ObjectUtils.isEmpty(platformEntity) && !ObjectUtils.isEmpty(productEntity)) {
                            //通知第三方平台
                            deviceService.sendThirdParty(deviceEntity, productEntity, platformEntity, DeviceMethodEnum.OFFLINE);
                            //保存业务消息为离线
                            BizLogPdu bizLogPdu = new BizLogPdu();
                            bizLogPdu.initAttrValue();
                            //保存为产品名称
                            bizLogPdu.setAppName(productEntity.getProductCode());
                            bizLogPdu.setTraceID(IdUtil.objectId());
                            bizLogPdu.setUserCode("system");
                            bizLogPdu.setDeviceCode(deviceEntity.getDeviceCode());
                            bizLogPdu.setEventTopic("offline");
                            bizLogPdu.setEventTopicName(LogTypeEnum.上报事件.name());
                            bizLogPdu.setMsg(Base64.encode("设备下线"));
                            bizLogPdu.setLogLevel("INFO");
                            bizLogPdu.setLogTime(new Date());
                            messageProducer.syncBizSend(bizLogPdu);

                            ErrorLogPdu errorLogPdu = new ErrorLogPdu();
                            errorLogPdu.initAttrValue();
                            errorLogPdu.setTraceID(IdUtil.objectId());
                            errorLogPdu.setAppName(productEntity.getProductCode());
                            errorLogPdu.setMessage(deviceEntity.getDeviceName() + deviceEntity.getDeviceCode() + "设备下线!");
                            errorLogPdu.setPlatform("webos");
                            errorLogPdu.setCulprit("");
                            errorLogPdu.setTags("");
                            errorLogPdu.setLevel("INFO");
                            errorLogPdu.setEnvironment("");
                            errorLogPdu.setReleaseVersion("");
                            errorLogPdu.setFingerprint(LogTypeEnum.上报事件.name());
                            errorLogPdu.setThreadNo(Thread.currentThread().toString());
                            errorLogPdu.setErrorStack(Thread.currentThread() + deviceEntity.getDeviceName() + deviceEntity.getDeviceCode() + "设备下线!");
                            errorLogPdu.setContext("");
                            errorLogPdu.setExtra("");
                            errorLogPdu.setLogTime(new Date());
                            messageProducer.syncErrorSend(errorLogPdu);

                            //生成异常日志
                        }

                        //保存离线告警消息
                        DeviceAlarmInfoEntity alarmInfoEntity = new DeviceAlarmInfoEntity();
                        alarmInfoEntity.initAttrValue();
                        alarmInfoEntity.setAlarmDevice(deviceEntity.getId());
                        alarmInfoEntity.setSiteId(deviceEntity.getSiteId());
                        alarmInfoEntity.setAlarmTime(new Date());
                        alarmInfoEntity.setDeviceName(deviceEntity.getDeviceName());
                        alarmInfoEntity.setDeviceCode(deviceEntity.getDeviceCode());
                        alarmInfoEntity.setAlarmContent(String.format("设备告警：%s设备：%s已离线，请注意检查！", productEntity.getProductName(), deviceEntity.getDeviceName() + ":" + deviceEntity.getDeviceName()));
                        alarmInfoEntity.setAlarmType(AlarmTypeEnum.离线.getValue());
                        alarmInfoEntity.setAlarmLevel(AlarmLevelEnum.一般.getValue());
                        alarmInfoEntity.setAlarmStatus(AlarmStatusEnum.未清除.getValue());
                        alarmInfoEntity.setAlarmReceivePersonnel(deviceEntity.getLeadingOfficial());
                        alarmInfoEntity.setReceivePersonnelTelephone(deviceEntity.getLeadingOfficialTelephone());
                        alarmInfoEntity.setCreateTime(new Date());
                        alarmInfoEntity.setCreateUserId(1L);
                        // TODO: 2022/6/23 告警信息保存与发送
                        AlarmConfigEntity alarmConfigEntity = alarmConfigService.selectOne(new AlarmConfigQuery().productId(productEntity.getId()));
                        if (!ObjectUtils.isEmpty(alarmConfigEntity)) {
/*                        if (alarmConfigEntity.getAlarmPusW1ay() == AlarmPusW1ayEnum.站内信息.getValue()) {
                        }*/
                            if (EnabledEnum.启用.getValue() == alarmConfigEntity.getEnabled()) {
                                alarmInfoEntity.setProductId(productEntity.getId());
                                alarmInfoEntity.setProductCode(productEntity.getProductCode());
                                alarmInfoEntity.setProductName(productEntity.getProductName());
                                alarmInfoEntity.setPush(YesNoEnum.YES.getValue());
                                deviceAlarmInfoService.save(alarmInfoEntity);
                            }

                            if (alarmConfigEntity.getAlarmPusW1ay() == AlarmPusW1ayEnum.短信.getValue()) {
                                // TODO: 2022/7/4 发送短信
                                Rest<RespData<List<SmsSetPdu>>> respDataRest = smsSetFeign.list(new SmsSetPdu().siteId(deviceEntity.getSiteId()));
                                if (respDataRest.getCode() == YesNoEnum.YES.getValue()) {
                                    List<SmsSetPdu> data = respDataRest.getData().getData();
                                    if (!ObjectUtils.isEmpty(data)) {
                                        Integer messageoff = data.get(0).getMessageoff();
                                        if (messageoff == YesNoEnum.YES.getValue()) {
                                            // todo 发送短信
                                            //短信使用模板，如 设备告警：{产品}设备：{设备名称加编码}已离线，请注意检查！
                                            int count = deviceAlarmInfoService.count(new DeviceAlarmInfoQuery().alarmDevice(deviceEntity.getId()), null);
                                            if (count > 0) {
                                                AlarmSmsSendEntity alarmSmsSendEntity = new AlarmSmsSendEntity();
                                                alarmSmsSendEntity.initAttrValue();
                                                alarmSmsSendEntity.setId(IdUtil.getSnowflake().nextId());
                                                alarmSmsSendEntity.setSiteId(deviceEntity.getSiteId());
                                                alarmSmsSendEntity.setMobile(deviceEntity.getLeadingOfficial());
                                                alarmSmsSendEntity.setReceiver(deviceEntity.getLeadingOfficialTelephone());
                                                Map<String, String> map = new HashMap<>();
                                                map.put("1", productEntity.getProductName());
                                                map.put("2", deviceEntity.getDeviceName() + ":" + deviceEntity.getDeviceName());
                                                alarmSmsSendEntity.setSendMess(JSON.toJSONString(map));
                                                alarmSmsSendEntity.setSendStatus(SendStatusEnum.未发送.getValue());
                                                alarmSmsSendService.save(alarmSmsSendEntity, null);
                                            }
                                        } else {
                                            //推送站类


                                        }
                                    }
                                }
                            }
                        }

                        // deviceAlarmInfoService.save(alarmInfoEntity);
                    }
                }
            }
        }
     //   log.info("监听到key:" + key + "过期");
    }
}