package org.springblade.mq.kafka.handler;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;

import org.springblade.constant.RedisBusinessConstant;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.core.tool.utils.ConcurrentDateFormat;
import org.springblade.core.tool.utils.Func;
import org.springblade.enums.*;
import org.springblade.modules.baseinfo.monitorsite.entity.MonitorSiteInfoEntity;
import org.springblade.modules.baseinfo.monitorsite.service.IMonitorSiteService;
import org.springblade.modules.baseinfo.rtu.entity.RtuInfoEntity;
import org.springblade.modules.baseinfo.rtu.service.IRtuBaseInfoService;
import org.springblade.modules.business.monitor.entity.WaterFlowRateHistoryInfoEntity;
import org.springblade.modules.business.monitor.entity.WaterFlowRateInfoEntity;
import org.springblade.modules.business.monitor.service.IWaterFlowRateHistoryService;
import org.springblade.modules.business.monitor.service.IWaterFlowRateService;
import org.springblade.modules.business.rtumanage.dto.RtuStatusDTO;
import org.springblade.modules.business.rtumanage.entity.RtuStatusEntity;
import org.springblade.modules.business.rtumanage.service.IRtuManageService;
import org.springblade.modules.business.warning.entity.RtuWarningInfoEntity;
import org.springblade.modules.business.warning.service.IRtuWarningService;
import org.springblade.utils.BytesHelp;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;


/**
 * 消息处理器
 *
 * @author
 */
@Slf4j
@Component
public class MessageHandler {

    @Resource
    private IWaterFlowRateHistoryService waterFlowRateHistoryService;

    @Resource
    private IWaterFlowRateService waterFlowRateService;

    @Resource
    private IRtuManageService rtuManageService;

    @Resource
    private IRtuWarningService rtuWarningService;

    @Resource
    private IMonitorSiteService monitorSiteService;

    @Resource
    private IRtuBaseInfoService  rtuBaseInfoService;

    @Resource
    private KafkaTemplate<String, String> kafkaTemplate;

    @Value("${spring.mq-topic.ywxt-rtu-status-update}")
    private String topicYwxtRtuStatus;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 报文
     * 流量数据
     *
     * @param record
     * @param acknowledgment
     */
    @KafkaListener(groupId = "${spring.kafka.consumer.group-id}", topics = "${spring.mq-topic.szy-water-flow-rate}", containerFactory = "ackContainerFactory")
    public void waterFlowRateMessage(ConsumerRecord record, Acknowledgment acknowledgment) {
        try {
            String message = (String) record.value();
            log.info("{} ,{}", "tddcs water flow rate  info", message);
            JSONObject body = JSONObject.parseObject(message);
            String rtuCode = body.getString(SzyFlowRateMetadataEnum.METADATA_RTU_CODE.getName());
            RtuInfoEntity rtuInfoEntity= rtuBaseInfoService.rtuInfoByRtuCode(rtuCode);
            if (Func.isNull(rtuInfoEntity)){
                rtuInfoEntity=new RtuInfoEntity();
                rtuInfoEntity.setRtuCode(rtuCode);
                rtuBaseInfoService.save(rtuInfoEntity);
            }

            WaterFlowRateHistoryInfoEntity historyInfoEntity = new WaterFlowRateHistoryInfoEntity();
            historyInfoEntity.setMpcd(rtuCode);
            historyInfoEntity.setMpq(body.getDouble(SzyFlowRateMetadataEnum.METADATA_CODE_Q.getName()));
            historyInfoEntity.setAccw(body.getLong(SzyFlowRateMetadataEnum.METADATA_CODE_ACC_Q.getName()));
            historyInfoEntity.setHourw(body.getLong(SzyFlowRateMetadataEnum.METADATA_CODE_HOUR_Q.getName()));
            historyInfoEntity.setTs(Func.parse(body.getString(SzyFlowRateMetadataEnum.METADATA_UP_TIME.getName()), ConcurrentDateFormat.of("yyyyMMddHHmmss")));
            historyInfoEntity.setTm(Func.parse(body.getString(SzyFlowRateMetadataEnum.METADATA_COLLECT_TIME.getName()), ConcurrentDateFormat.of("yyyyMMddHHmmss")));
            waterFlowRateHistoryService.save(historyInfoEntity);
            LambdaQueryWrapper<WaterFlowRateInfoEntity> wrapper = Wrappers.<WaterFlowRateInfoEntity>query().lambda();
            wrapper.eq(WaterFlowRateInfoEntity::getMpcd, historyInfoEntity.getMpcd());
            WaterFlowRateInfoEntity entity = waterFlowRateService.getOne(wrapper);
            if (null == entity) {
                entity = new WaterFlowRateInfoEntity();
                entity.setMpcd(historyInfoEntity.getMpcd());
            }
            entity.setMpq(historyInfoEntity.getMpq());
            entity.setAccw(historyInfoEntity.getAccw());
            entity.setHourw(historyInfoEntity.getHourw());
            entity.setTs(historyInfoEntity.getTs());
            entity.setTm(historyInfoEntity.getTm());
            waterFlowRateService.saveOrUpdate(entity);


            //更新测站最新上报时间
            HashOperations<String, String, String> hashops = redisTemplate.opsForHash();
            String key = RedisBusinessConstant.KEY_RTU_RUN_INFO + rtuCode;
            String lastDatetimeText = hashops.get(key, RedisBusinessConstant.KEY_RTU_RUN_INFO_LAST_TIME);
            if (null != lastDatetimeText && lastDatetimeText.length() > 0) {
                LocalDateTime lastDateTime = LocalDateTime.parse(lastDatetimeText, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                LocalDateTime tm = LocalDateTime.ofInstant(entity.getTm().toInstant(), ZoneId.systemDefault());
                if (tm.isAfter(lastDateTime)) {
                    lastDatetimeText = Func.formatDateTime(entity.getTm());
                    hashops.put(key, RedisBusinessConstant.KEY_RTU_RUN_INFO_LAST_TIME, lastDatetimeText);
                }
            } else {
                lastDatetimeText = Func.formatDateTime(entity.getTm());
                hashops.put(key, RedisBusinessConstant.KEY_RTU_RUN_INFO_LAST_TIME, lastDatetimeText);
            }

            //测站状态检测
            RtuStatusDTO statusEntity = new RtuStatusDTO();
            if (null != entity.getTm()) {
                statusEntity.setLastUpTime(entity.getTm());
            } else if (null != entity.getTs()) {
                statusEntity.setLastUpTime(entity.getTs());
            } else {
                statusEntity.setLastUpTime(new Date());
            }
            statusEntity.setRtuCode(rtuCode);
            statusEntity.setIsRiver(1);
            statusEntity.setFromDate(entity.getTs());
            kafkaTemplate.send(topicYwxtRtuStatus, JsonUtil.toJson(statusEntity));


        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            // 手动提交 offset
            acknowledgment.acknowledge();
        }
    }

    /**
     * 报文
     * 水位数据
     *
     * @param record
     * @param acknowledgment
     */
    @KafkaListener(groupId = "${spring.kafka.consumer.group-id}", topics = "${spring.mq-topic.szy-water-level}", containerFactory = "ackContainerFactory")
    public void waterLevelMessage(ConsumerRecord record, Acknowledgment acknowledgment) {
        try {
            String message = (String) record.value();
            log.info("{} ,{}", "tddcs water level info", message);
            JSONObject body = JSONObject.parseObject(message);
            String rtuCode = body.getString(SzyFlowRateMetadataEnum.METADATA_RTU_CODE.getName());
            RtuInfoEntity rtuInfoEntity= rtuBaseInfoService.rtuInfoByRtuCode(rtuCode);
            if (Func.isNull(rtuInfoEntity)){
                rtuInfoEntity=new RtuInfoEntity();
                rtuInfoEntity.setRtuCode(rtuCode);
                rtuBaseInfoService.save(rtuInfoEntity);
            }
            WaterFlowRateHistoryInfoEntity historyInfoEntity = new WaterFlowRateHistoryInfoEntity();
           // String rtuCode = body.getString(SzyFlowRateMetadataEnum.METADATA_RTU_CODE.getName());

            historyInfoEntity.setMpcd(rtuCode);


            double waterLevel = body.getDouble(SzyWaterLevelMetadataEnum.METADATA_CODE_LEVEL.getName());

            historyInfoEntity.setWaterLevel(waterLevel);

            historyInfoEntity.setTs(Func.parse(body.getString(SzyFlowRateMetadataEnum.METADATA_UP_TIME.getName()), ConcurrentDateFormat.of("yyyyMMddHHmmss")));
            historyInfoEntity.setTm(Func.parse(body.getString(SzyFlowRateMetadataEnum.METADATA_COLLECT_TIME.getName()), ConcurrentDateFormat.of("yyyyMMddHHmmss")));
            waterFlowRateHistoryService.save(historyInfoEntity);
            LambdaQueryWrapper<WaterFlowRateInfoEntity> wrapper = Wrappers.<WaterFlowRateInfoEntity>query().lambda();
            wrapper.eq(WaterFlowRateInfoEntity::getMpcd, historyInfoEntity.getMpcd());
            WaterFlowRateInfoEntity entity = waterFlowRateService.getOne(wrapper);
            if (null == entity) {
                entity = new WaterFlowRateInfoEntity();
                entity.setMpcd(historyInfoEntity.getMpcd());
            }
            entity.setWaterLevel(historyInfoEntity.getWaterLevel());

            entity.setTs(historyInfoEntity.getTs());
            entity.setTm(historyInfoEntity.getTm());
            waterFlowRateService.saveOrUpdate(entity);


            //更新测站最新上报时间
            HashOperations<String, String, String> hashops = redisTemplate.opsForHash();
            String key = RedisBusinessConstant.KEY_RTU_RUN_INFO + rtuCode;
            String lastDatetimeText = hashops.get(key, RedisBusinessConstant.KEY_RTU_RUN_INFO_LAST_TIME);
            if (null != lastDatetimeText && lastDatetimeText.length() > 0) {
                LocalDateTime lastDateTime = LocalDateTime.parse(lastDatetimeText, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                LocalDateTime tm = LocalDateTime.ofInstant(entity.getTm().toInstant(), ZoneId.systemDefault());
                if (tm.isAfter(lastDateTime)) {
                    lastDatetimeText = Func.formatDateTime(entity.getTm());
                    hashops.put(key, RedisBusinessConstant.KEY_RTU_RUN_INFO_LAST_TIME, lastDatetimeText);
                }
            } else {
                lastDatetimeText = Func.formatDateTime(entity.getTm());
                hashops.put(key, RedisBusinessConstant.KEY_RTU_RUN_INFO_LAST_TIME, lastDatetimeText);
            }

            //测站状态检测
            RtuStatusDTO statusEntity = new RtuStatusDTO();
            if (null != entity.getTm()) {
                statusEntity.setLastUpTime(entity.getTm());
            } else if (null != entity.getTs()) {
                statusEntity.setLastUpTime(entity.getTs());
            } else {
                statusEntity.setLastUpTime(new Date());
            }
            statusEntity.setRtuCode(rtuCode);
            statusEntity.setIsRiver(1);
            statusEntity.setFromDate(entity.getTs());
            kafkaTemplate.send(topicYwxtRtuStatus, JsonUtil.toJson(statusEntity));


        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            // 手动提交 offset
            acknowledgment.acknowledge();
        }
    }

    /**
     * 流速数据
     *
     * @param record
     * @param acknowledgment
     */
    @KafkaListener(groupId = "${spring.kafka.consumer.group-id}", topics = "${spring.mq-topic.szy-flow-speed}", containerFactory = "ackContainerFactory")
    public void flowSpeedMessage(ConsumerRecord record, Acknowledgment acknowledgment) {
        try {
            String message = (String) record.value();
            log.info("{} ,{}", "tddcs flow speed info", message);
            JSONObject body = JSONObject.parseObject(message);
            String rtuCode = body.getString(SzyFlowRateMetadataEnum.METADATA_RTU_CODE.getName());
            RtuInfoEntity rtuInfoEntity= rtuBaseInfoService.rtuInfoByRtuCode(rtuCode);
            if (Func.isNull(rtuInfoEntity)){
                rtuInfoEntity=new RtuInfoEntity();
                rtuInfoEntity.setRtuCode(rtuCode);
                rtuBaseInfoService.save(rtuInfoEntity);
            }
            WaterFlowRateHistoryInfoEntity historyInfoEntity = new WaterFlowRateHistoryInfoEntity();
           // String rtuCode = body.getString(SzyFlowRateMetadataEnum.METADATA_RTU_CODE.getName());
            historyInfoEntity.setMpcd(rtuCode);
            if (body.containsKey("FLOWSPEED")) {
                double flowSpeed = body.getDouble("FLOWSPEED");
                historyInfoEntity.setFlowSpeed(flowSpeed);
            }
            historyInfoEntity.setTs(Func.parse(body.getString(SzyFlowRateMetadataEnum.METADATA_UP_TIME.getName()), ConcurrentDateFormat.of("yyyyMMddHHmmss")));
            historyInfoEntity.setTm(Func.parse(body.getString(SzyFlowRateMetadataEnum.METADATA_COLLECT_TIME.getName()), ConcurrentDateFormat.of("yyyyMMddHHmmss")));
            waterFlowRateHistoryService.save(historyInfoEntity);
            LambdaQueryWrapper<WaterFlowRateInfoEntity> wrapper = Wrappers.<WaterFlowRateInfoEntity>query().lambda();
            wrapper.eq(WaterFlowRateInfoEntity::getMpcd, historyInfoEntity.getMpcd());
            WaterFlowRateInfoEntity entity = waterFlowRateService.getOne(wrapper);
            if (null == entity) {
                entity = new WaterFlowRateInfoEntity();
                entity.setMpcd(historyInfoEntity.getMpcd());
            }
            if (body.containsKey("FLOWSPEED")) {
                double flowSpeed = body.getDouble("FLOWSPEED");
                entity.setFlowSpeed(flowSpeed);
            }
            entity.setTs(historyInfoEntity.getTs());
            entity.setTm(historyInfoEntity.getTm());
            waterFlowRateService.saveOrUpdate(entity);
            //更新测站最新上报时间
            HashOperations<String, String, String> hashops = redisTemplate.opsForHash();
            String key = RedisBusinessConstant.KEY_RTU_RUN_INFO + rtuCode;
            String lastDatetimeText = hashops.get(key, RedisBusinessConstant.KEY_RTU_RUN_INFO_LAST_TIME);
            if (null != lastDatetimeText && lastDatetimeText.length() > 0) {
                LocalDateTime lastDateTime = LocalDateTime.parse(lastDatetimeText, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                LocalDateTime tm = LocalDateTime.ofInstant(entity.getTm().toInstant(), ZoneId.systemDefault());
                if (tm.isAfter(lastDateTime)) {
                    lastDatetimeText = Func.formatDateTime(entity.getTm());
                    hashops.put(key, RedisBusinessConstant.KEY_RTU_RUN_INFO_LAST_TIME, lastDatetimeText);
                }
            } else {
                lastDatetimeText = Func.formatDateTime(entity.getTm());
                hashops.put(key, RedisBusinessConstant.KEY_RTU_RUN_INFO_LAST_TIME, lastDatetimeText);
            }
            //测站状态检测
            RtuStatusDTO statusEntity = new RtuStatusDTO();
            if (null != entity.getTm()) {
                statusEntity.setLastUpTime(entity.getTm());
            } else if (null != entity.getTs()) {
                statusEntity.setLastUpTime(entity.getTs());
            } else {
                statusEntity.setLastUpTime(new Date());
            }
            statusEntity.setRtuCode(rtuCode);
            statusEntity.setIsRiver(1);
            statusEntity.setFromDate(entity.getTs());
            kafkaTemplate.send(topicYwxtRtuStatus, JsonUtil.toJson(statusEntity));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            // 手动提交 offset
            acknowledgment.acknowledge();
        }
    }


    @KafkaListener(groupId = "${spring.kafka.consumer.group-id}", topics = "${spring.mq-topic.szy-rtu-status}", containerFactory = "ackContainerFactory")
    public void rtuStatusMessage(ConsumerRecord record, Acknowledgment acknowledgment) {
        try {
            String message = (String) record.value();
            JSONObject body = JSONObject.parseObject(message);
            log.info("{} ,{}", "tddcs rtu status info", body.toJSONString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            // 手动提交 offset
            acknowledgment.acknowledge();
        }
    }

    @KafkaListener(groupId = "${spring.kafka.consumer.group-id}", topics = "${spring.mq-topic.szy-rtu-warn}", containerFactory = "ackContainerFactory")
    public void rtuWarnMessage(ConsumerRecord record, Acknowledgment acknowledgment) {
        try {
            String message = (String) record.value();
            JSONObject body = JSONObject.parseObject(message);
            log.info("{} ,{}", "tddcs rtu warn info", body.toJSONString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            // 手动提交 offset
            acknowledgment.acknowledge();
        }
    }

    @KafkaListener(groupId = "${spring.kafka.consumer.group-id}", topics = "${spring.mq-topic.ywxt-rtu-status-update}", containerFactory = "ackContainerFactory")
    public void ywxtRtuStatusMessage(ConsumerRecord record, Acknowledgment acknowledgment) {
        try {
            String message = (String) record.value();
            log.info("{} ,{}", "ywxt rtu status update", message);
            RtuStatusDTO dto = JsonUtil.parse(message, RtuStatusDTO.class);
            //更新测站最新上报时间状态
            RtuStatusEntity statusEntity = new RtuStatusEntity();
            statusEntity.setRtuCode(dto.getRtuCode());
            statusEntity.setLastUpTime(dto.getLastUpTime());
            rtuManageService.updateLastTime(statusEntity);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            // 手动提交 offset
            acknowledgment.acknowledge();
        }
    }

    @KafkaListener(groupId = "${spring.kafka.consumer.group-id}", topics = "${spring.mq-topic.ywxt-warning}", containerFactory = "ackContainerFactory")
    public void ywxtWarnMessage(ConsumerRecord record, Acknowledgment acknowledgment) {
        try {
            String message = (String) record.value();
            log.info("{} ,{}", "ywxt warn info", message);
            RtuWarningInfoEntity warningInfoEntity = JsonUtil.parse(message, RtuWarningInfoEntity.class);
            int statusCode = warningInfoEntity.getWarningStatus();
            if (statusCode == WarningStatusEnum.STATUS_HAPPEN.getCode()) {
                //更新测站运行状态
                RtuStatusEntity statusEntity = new RtuStatusEntity();
                statusEntity.setRtuCode(warningInfoEntity.getRtuCode());
                statusEntity.setRunStatusId(EquipmentStatusEnum.STATUS_FAILURE.getCode());
                rtuManageService.updateRtuStatus(statusEntity);
            } else if (statusCode == WarningStatusEnum.STATUS_CLOSE.getCode()) {
                //所有预警已经关闭
                LambdaQueryWrapper<RtuWarningInfoEntity> warningWrapper = Wrappers.<RtuWarningInfoEntity>query().lambda();
                warningWrapper.eq(RtuWarningInfoEntity::getRtuCode, warningInfoEntity.getRtuCode());
                warningWrapper.eq(RtuWarningInfoEntity::getWarningStatus, WarningStatusEnum.STATUS_HAPPEN.getCode());
                List<RtuWarningInfoEntity> warningInfoEntityList = rtuWarningService.list(warningWrapper);
                if (null == warningInfoEntityList || warningInfoEntityList.size() == 0) {
                    //更新测站运行状态
                    RtuStatusEntity statusEntity = new RtuStatusEntity();
                    statusEntity.setRtuCode(warningInfoEntity.getRtuCode());
                    statusEntity.setRunStatusId(EquipmentStatusEnum.STATUS_RUN.getCode());
                    rtuManageService.updateRtuStatus(statusEntity);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            // 手动提交 offset
            acknowledgment.acknowledge();
        }
    }
}
