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.PerceptionMonitorInfoService;
import com.lutao.cloud.consume.service.ProcessParameterTagService;
import com.lutao.cloud.consume.util.TimeUtil;
import com.lutao.entity.PerceptionDynamic;
import com.lutao.entity.PerceptionMonitorInfo;
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 PerceptionMonitorInfoStrategy implements CommandStrategy<PerceptionMonitorInfo> {

//    @Resource
//    private LindormTSDBClient lindormTSDBClient;

    @Resource
    private PerceptionMonitorInfoService perceptionMonitorInfoService;

    @Resource
    private ProcessParameterTagService processParameterTagService;

    @Resource
    private PerceptionDynamicService perceptionDynamicService;

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


    private static PerceptionMonitorInfoStrategy perceptionMonitorInfoStrategy;

    @PostConstruct
    public void init() {
        perceptionMonitorInfoStrategy = this;
        perceptionMonitorInfoStrategy.perceptionMonitorInfoService = this.perceptionMonitorInfoService;
        perceptionMonitorInfoStrategy.processParameterTagService = this.processParameterTagService;
        perceptionMonitorInfoStrategy.perceptionDynamicService = this.perceptionDynamicService;
        perceptionMonitorInfoStrategy.redisTemplate = this.redisTemplate;
    }

    @Override
    public MessageInfo execute(String command, JsonNode data, DataAddVO dataAddVO) {
        if (MessageCommandEnum.MESSAGE_ADD.getCommand().equals(command)) {
            log.info(data.toString());
            PerceptionMonitorInfo perceptionMonitorInfo = JSONUtil.toBean(data.toString(), PerceptionMonitorInfo.class);
            perceptionMonitorInfo.setAppId(dataAddVO.getAppId());
            String tagCode = perceptionMonitorInfo.getTagCode();
            PerceptionDynamic perceptionDynamic = new PerceptionDynamic();
            perceptionDynamic.setTagCode(tagCode);
            perceptionDynamic.setAppId(perceptionMonitorInfo.getAppId());
            perceptionDynamic.setRtValue(perceptionMonitorInfo.getRtValue());
            perceptionDynamic.setCollectTime(perceptionMonitorInfo.getCollectTime());
            perceptionDynamic.setCreateTime(perceptionMonitorInfo.getCreateTime());
            perceptionDynamic.setUpdateTime(perceptionMonitorInfo.getUpdateTime());
            perceptionMonitorInfoStrategy.perceptionDynamicService.saveOrUpdate(perceptionDynamic, Wrappers.lambdaQuery(PerceptionDynamic.class)
                    .eq(PerceptionDynamic::getAppId, perceptionDynamic.getAppId())
                    .eq(PerceptionDynamic::getTagCode, perceptionDynamic.getTagCode()));
            perceptionMonitorInfoStrategy.perceptionMonitorInfoService.save(perceptionMonitorInfo);


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

        }
        return MessageInfo.ok();

    }

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

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

        if (MessageCommandEnum.MESSAGE_ADD.getCommand().equals(command)) {
            log.info("PerceptionMonitorInfoStrategy 进行add-Batch操作 ......");
            perceptionMonitorInfoStrategy.perceptionMonitorInfoService.saveBatch(perceptionMonitorInfos);
        }

        return MessageInfo.ok();
    }
}
