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.PerceptionMonitorGasInfoService;
import com.lutao.cloud.consume.util.TimeUtil;
import com.lutao.entity.PerceptionDynamic;
import com.lutao.entity.PerceptionMonitorGasInfo;
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 PerceptionMonitorGasInfoStrategy implements CommandStrategy<PerceptionMonitorGasInfo> {

//    @Resource
//    private LindormTSDBClient lindormTSDBClient;

    @Resource
    private PerceptionMonitorGasInfoService perceptionMonitorGasInfoService;

    private static PerceptionMonitorGasInfoStrategy perceptionMonitorGasInfoStrategy;

    @Resource
    private PerceptionDynamicService perceptionDynamicService;

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


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

    }

    @Override
    public MessageInfo execute(String command, JsonNode data, DataAddVO dataAddVO) {
        if (MessageCommandEnum.MESSAGE_ADD.getCommand().equals(command)) {
            PerceptionMonitorGasInfo perceptionMonitorGasInfo = JSONUtil.toBean(data.toString(), PerceptionMonitorGasInfo.class);
            perceptionMonitorGasInfo.setAppId(dataAddVO.getAppId());
            log.info("PerceptionMonitorGasInfoStrategy 进行add操作 ......");

            String tagCode = perceptionMonitorGasInfo.getTagCode();

            PerceptionDynamic perceptionDynamic = new PerceptionDynamic();
            perceptionDynamic.setTagCode(tagCode);
            perceptionDynamic.setAppId(perceptionMonitorGasInfo.getAppId());
            perceptionDynamic.setRtValue(perceptionMonitorGasInfo.getRtValue());
            perceptionDynamic.setCollectTime(perceptionMonitorGasInfo.getCollectTime());
            perceptionDynamic.setCreateTime(perceptionMonitorGasInfo.getCreateTime());
            perceptionDynamic.setUpdateTime(perceptionMonitorGasInfo.getUpdateTime());
            perceptionMonitorGasInfoStrategy.perceptionDynamicService.saveOrUpdate(perceptionDynamic, Wrappers.lambdaQuery(PerceptionDynamic.class)
                    .eq(PerceptionDynamic::getAppId, perceptionDynamic.getAppId())
                    .eq(PerceptionDynamic::getTagCode, perceptionDynamic.getTagCode()));

            perceptionMonitorGasInfoStrategy.perceptionMonitorGasInfoService.save(perceptionMonitorGasInfo);

            //表名-appid-平台-code
            BoundHashOperations perceptionMonitorGasInfoCache = perceptionMonitorGasInfoStrategy.redisTemplate.boundHashOps(LocalDate.now() + ":" + dataAddVO.getResource() + ":"
                    + perceptionMonitorGasInfo.getAppId() + ":" + perceptionMonitorGasInfo.getPlatformCode() + ":" + perceptionMonitorGasInfo.getTagCode());
            Integer enable = (Integer) perceptionMonitorGasInfoCache.get("enable");
            if (enable != null && enable == 0){
                try {
                    // 获取当前时间字符串
                    String currentTimeStr = LocalDateTime.now().toString();
                    // 获取已接收计数
                    Integer receivedCount = (Integer) perceptionMonitorGasInfoCache.get("received_count");
                    if (Objects.isNull(receivedCount) || receivedCount < 1) {
                        // 初始化缓存条目
                        perceptionMonitorGasInfoCache.put("received_time", currentTimeStr);
                        perceptionMonitorGasInfoCache.put("entity", JSONUtil.toJsonStr(perceptionMonitorGasInfo));
                        perceptionMonitorGasInfoCache.put("resource", dataAddVO.getResource());
                        perceptionMonitorGasInfoCache.increment("received_count", 1);
                        perceptionMonitorGasInfoCache.put("value", perceptionMonitorGasInfo.getRtValue());
                        // 设置过期时间
                        perceptionMonitorGasInfoCache.expire(48, TimeUnit.HOURS);
                    } else {
                        // 检查是否需要更新
                        String lastReceivedTime = (String) perceptionMonitorGasInfoCache.get("received_time");
                        String currentValue = (String) perceptionMonitorGasInfoCache.get("value");
                        String newRtValue = perceptionMonitorGasInfo.getRtValue().toString();
                        if (!currentTimeStr.equals(lastReceivedTime) && currentValue != null && currentValue != newRtValue) {
                            perceptionMonitorGasInfoCache.increment("received_count", 1);
                            // 计算每分钟应该接受的数据量
                            LocalDateTime beginTime = LocalDateTime.parse(perceptionMonitorGasInfoCache.get("begin_time").toString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
                            Long shouldAcceptCount = TimeUtil.getTimeDifference(beginTime, LocalDateTime.now());
                            perceptionMonitorGasInfoCache.put("should_accept_count", shouldAcceptCount);
                            // 更新缓存条目
                            perceptionMonitorGasInfoCache.put("entity", JSONUtil.toJsonStr(perceptionMonitorGasInfo));
                            if (shouldAcceptCount>0){
                                perceptionMonitorGasInfoCache.put("online_rate",String.valueOf((float) receivedCount / shouldAcceptCount));
                            }
                            perceptionMonitorGasInfoCache.put("received_time", currentTimeStr);
                            perceptionMonitorGasInfoCache.put("value", newRtValue);
                        }
                    }
                } catch (Exception e) {
                    log.error("更新感知监控气体信息缓存异常", e);
                }
            }

        }
        return MessageInfo.ok();

    }

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

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

        if (MessageCommandEnum.MESSAGE_ADD.getCommand().equals(command)) {
            log.info("PerceptionMonitorGasInfoStrategy 进行add-Batch操作 ......");
            perceptionMonitorGasInfoStrategy.perceptionMonitorGasInfoService.saveBatch(perceptionMonitorGasInfos);
        }

        return MessageInfo.ok();
    }
}
