package com.lutao.cloud.consume.factory;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.JsonNode;
import com.lutao.cloud.collect.vo.DataAddVO;
import com.lutao.cloud.common.core.kafka.MessageCommandEnum;
import com.lutao.cloud.common.core.util.MessageInfo;
import com.lutao.cloud.consume.service.PerceptionDynamicService;
import com.lutao.cloud.consume.service.PerceptionMonitorFireInfoService;
import com.lutao.cloud.consume.util.TimeUtil;
import com.lutao.entity.PerceptionDynamic;
import com.lutao.entity.PerceptionMonitorFireInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 感知监测信息
 *
 * @author yx
 * @date 2023/07/21
 */
@Component
@Slf4j
public class PerceptionMonitorFireInfoStrategy implements CommandStrategy<PerceptionMonitorFireInfo> {

//    @Resource
//    private LindormTSDBClient lindormTSDBClient;

    @Resource
    private PerceptionMonitorFireInfoService perceptionMonitorFireInfoService;

    private static PerceptionMonitorFireInfoStrategy perceptionMonitorFireInfoStrategy;

    @Resource
    private PerceptionDynamicService perceptionDynamicService;

    @Resource(name = "redisTemplateAlias")
    private RedisTemplate redisTemplate;

    @PostConstruct
    public void init() {
        perceptionMonitorFireInfoStrategy = this;
        perceptionMonitorFireInfoStrategy.perceptionMonitorFireInfoService = this.perceptionMonitorFireInfoService;
        perceptionMonitorFireInfoStrategy.perceptionDynamicService = this.perceptionDynamicService;
        //perceptionMonitorFireInfoStrategy.lindormTSDBClient = this.lindormTSDBClient;
        perceptionMonitorFireInfoStrategy.redisTemplate = this.redisTemplate;

    }

    @Override
    public MessageInfo execute(String command, JsonNode data, DataAddVO dataAddVO) {
        if (MessageCommandEnum.MESSAGE_ADD.getCommand().equals(command)) {
            PerceptionMonitorFireInfo perceptionMonitorFireInfo = JSONUtil.toBean(data.toString(), PerceptionMonitorFireInfo.class);
            perceptionMonitorFireInfo.setAppId(dataAddVO.getAppId());
            log.info("PerceptionMonitorFireInfoStrategy 进行add操作 ......");
            String tagCode = perceptionMonitorFireInfo.getTagCode();
            PerceptionDynamic perceptionDynamic = new PerceptionDynamic();
            perceptionDynamic.setTagCode(tagCode);
            perceptionDynamic.setAppId(perceptionMonitorFireInfo.getAppId());
            perceptionDynamic.setRtValue(perceptionMonitorFireInfo.getRtValue());
            perceptionDynamic.setCollectTime(perceptionMonitorFireInfo.getCollectTime());
            perceptionDynamic.setCreateTime(perceptionMonitorFireInfo.getCreateTime());
            perceptionDynamic.setUpdateTime(perceptionMonitorFireInfo.getUpdateTime());
            perceptionMonitorFireInfoStrategy.perceptionDynamicService.saveOrUpdate(perceptionDynamic, Wrappers.lambdaQuery(PerceptionDynamic.class)
                    .eq(PerceptionDynamic::getAppId, perceptionDynamic.getAppId())
                    .eq(PerceptionDynamic::getTagCode, perceptionDynamic.getTagCode()));

            perceptionMonitorFireInfoStrategy.perceptionMonitorFireInfoService.save(perceptionMonitorFireInfo);


            //表名-appid-平台-code
            BoundHashOperations perceptionMonitorFireInfoCache = perceptionMonitorFireInfoStrategy.redisTemplate.boundHashOps(LocalDate.now() + ":" + dataAddVO.getResource() + ":"
                    + perceptionMonitorFireInfo.getAppId() + ":" + perceptionMonitorFireInfo.getPlatformCode() + ":" + perceptionMonitorFireInfo.getTagCode());
            Integer enable = (Integer) perceptionMonitorFireInfoCache.get("enable");
            log.info("----------------是否启用------------:" + enable);
            if (enable != null && enable == 0) {
                try {
                    log.info(perceptionMonitorFireInfo.getTagCode() + "启用-------------------");
                    // 获取当前时间字符串
                    String currentTimeStr = perceptionMonitorFireInfo.getCollectTime().toString();
                    // 检查是否需要更新
                    String lastReceivedTime = (String) perceptionMonitorFireInfoCache.get("received_time");
                    Double currentValue = (Double) perceptionMonitorFireInfoCache.get("value");
                    Double newRtValue = perceptionMonitorFireInfo.getRtValue();
                    boolean b = !currentTimeStr.equals(lastReceivedTime)  || !(newRtValue.equals(currentValue));
                    log.info("-----------检查是否需要更新-------------" + b);
                    if (b) {
                        log.info("-----------更新缓存条目-------------");
                        perceptionMonitorFireInfoCache.increment("received_count", 1);
                        // 计算每分钟应该接受的数据量
                        LocalDateTime beginTime = LocalDateTime.parse(perceptionMonitorFireInfoCache.get("begin_time").toString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
                        Long shouldAcceptCount = TimeUtil.getTimeDifference(beginTime, LocalDateTime.now());
                        perceptionMonitorFireInfoCache.put("should_accept_count", shouldAcceptCount);
                        // 获取已接收计数
                        Integer receivedCount = (Integer) perceptionMonitorFireInfoCache.get("received_count");
                        log.info("receivedCount:" + receivedCount);
                        if (shouldAcceptCount > 0) {
                            perceptionMonitorFireInfoCache.put("online_rate", (float) receivedCount / shouldAcceptCount);
                        }
                        perceptionMonitorFireInfoCache.put("entity", JSONUtil.toJsonStr(perceptionMonitorFireInfo));
                        perceptionMonitorFireInfoCache.put("received_time", currentTimeStr);
                        perceptionMonitorFireInfoCache.put("value", newRtValue);
                        perceptionMonitorFireInfoCache.put("resource", dataAddVO.getResource());
                    }

                } catch (Exception e) {
                    log.error("更新感知监控火气信息缓存异常", e);
                    e.printStackTrace();
                }
            }


        }

        return MessageInfo.ok();

    }

    @Override
    public MessageInfo executeBatch(List<DataAddVO> dataAddVOS) {
        List<PerceptionMonitorFireInfo> perceptionMonitorFireInfos = new ArrayList<>();
        for (DataAddVO dataAddVO : dataAddVOS) {
            PerceptionMonitorFireInfo perceptionMonitorFireInfo = JSONUtil.toBean(dataAddVO.getJsonDate().toString(), PerceptionMonitorFireInfo.class);
            perceptionMonitorFireInfo.setAppId(dataAddVO.getAppId());
            perceptionMonitorFireInfos.add(perceptionMonitorFireInfo);
        }

        String command = dataAddVOS.get(0).getCommand();

        if (MessageCommandEnum.MESSAGE_ADD.getCommand().equals(command)) {
            log.info("PerceptionMonitorFireInfoStrategy 进行add-Batch操作 ......");
            perceptionMonitorFireInfoStrategy.perceptionMonitorFireInfoService.saveBatch(perceptionMonitorFireInfos);
        }

        return MessageInfo.ok();
    }
}
