package com.lutao.cloud.consume.kafka.consumer;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lutao.cloud.collect.vo.DataAddVO;
import com.lutao.cloud.common.core.util.StringUtil;
import com.lutao.entity.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.BoundZSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.annotation.KafkaHandler;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.Set;

/**
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
@Component
@Slf4j
@KafkaListener(topics = {"oceancrude_dynamic_data_topic"}, groupId = "dynamic-redis-consumer-group")
@AllArgsConstructor
public class DynamicToRedisConsumer {


    @Resource
    private RedisTemplate redisTemplate;


    /**
     * 接收消息处理
     * SINGLE_MESSAGE 单条消息类型
     * ROLE_GROUP_MESSAGE 根据角色处理消息
     *
     * @param message
     */
    @KafkaHandler
    public void receive(String message) {
        if (StringUtil.isNotBlank(message)) {
            log.info("static-redis-consumer-group receive message:{}", message);
            DataAddVO dataAddVO = convertMessageToEntity(message);
            //需要操作的数据表
            String resource = dataAddVO.getResource();
            //date里面的数据
            JsonNode jsonDate = dataAddVO.getJsonDate();

            switch (resource) {
                case "perception_monitor_info":
                    PerceptionMonitorInfo perceptionMonitorInfo = JSONUtil.toBean(jsonDate.toString(), PerceptionMonitorInfo.class);
                    perceptionMonitorInfo.setAppId(dataAddVO.getAppId());
                    sendToRedis(resource,resource + ":" + perceptionMonitorInfo.getPlatformCode(),perceptionMonitorInfo,Timestamp.valueOf(perceptionMonitorInfo.getCollectTime()).getTime());
                    log.info("动态数据：perception_monitor_info，平台名称：" + perceptionMonitorInfo.getPlatformCode() + "入Redis已完成");
                    break;
                case "perception_monitor_fire_info":
                    PerceptionMonitorFireInfo perceptionMonitorFireInfo = JSONUtil.toBean(jsonDate.toString(), PerceptionMonitorFireInfo.class);
                    perceptionMonitorFireInfo.setAppId(dataAddVO.getAppId());
                    sendToRedis(resource,resource + ":" + perceptionMonitorFireInfo.getPlatformCode(),perceptionMonitorFireInfo,Timestamp.valueOf(perceptionMonitorFireInfo.getCollectTime()).getTime());
                    log.info("动态数据：perception_monitor_fire_info，平台名称：" + perceptionMonitorFireInfo.getPlatformCode() + "入Redis已完成");
                    break;
                case "perception_monitor_gas_info":
                    PerceptionMonitorGasInfo perceptionMonitorGasInfo = JSONUtil.toBean(jsonDate.toString(), PerceptionMonitorGasInfo.class);
                    perceptionMonitorGasInfo.setAppId(dataAddVO.getAppId());
                    sendToRedis(resource,resource + ":" + perceptionMonitorGasInfo.getPlatformCode(),perceptionMonitorGasInfo,Timestamp.valueOf(perceptionMonitorGasInfo.getCollectTime()).getTime());
                    log.info("动态数据：perception_monitor_gas_info，平台名称：" + perceptionMonitorGasInfo.getPlatformCode() + "入Redis已完成");
                    break;
                case "perception_monitor_hazardous_gas_info":
                    PerceptionMonitorHazardousGasInfo perceptionMonitorHazardousGasInfo = JSONUtil.toBean(jsonDate.toString(), PerceptionMonitorHazardousGasInfo.class);
                    perceptionMonitorHazardousGasInfo.setAppId(dataAddVO.getAppId());
                    sendToRedis(resource,resource + ":" + perceptionMonitorHazardousGasInfo.getPlatformCode(),perceptionMonitorHazardousGasInfo,Timestamp.valueOf(perceptionMonitorHazardousGasInfo.getCollectTime()).getTime());
                    log.info("动态数据：perception_monitor_hazardous_gas_info，平台名称：" + perceptionMonitorHazardousGasInfo.getPlatformCode() + "入Redis已完成");
                    break;
                case "atmosphere_monitor_info":
                    AtmosphereMonitorInfo atmosphereMonitorInfo = JSONUtil.toBean(jsonDate.toString(), AtmosphereMonitorInfo.class);
                    atmosphereMonitorInfo.setAppId(dataAddVO.getAppId());
                    sendToRedis(resource,resource + ":" + atmosphereMonitorInfo.getPlatformCode(),atmosphereMonitorInfo,Timestamp.valueOf(atmosphereMonitorInfo.getDetectionTime()).getTime());
                    log.info("动态数据：atmosphere_monitor_info，平台名称：" + atmosphereMonitorInfo.getPlatformCode() + "入Redis已完成");
                    break;
            }
        }
    }

    public void sendToRedis(String key,String keyCode,Object obj,Long time){
        Long recordSize = 20L;
        BoundZSetOperations boundZSetOperations = redisTemplate.boundZSetOps(keyCode);
        boundZSetOperations.add(obj, time);
        BoundZSetOperations boundZSetOperations1 = redisTemplate.boundZSetOps(key);
        boundZSetOperations1.add(obj, time);
        //log.info("动态数据：perception_monitor_info，平台名称：" + perceptionMonitorInfo.getPlatformCode() + "入Redis已完成");
        Long size = boundZSetOperations.size();
        assert size != null;
        if (size.intValue() > recordSize) {
            boundZSetOperations.removeRange(0, size - recordSize);
            log.info("sendToRedis size:{} remove {} 0-{}",size,key,size-recordSize);
        }
        Long platformsize = boundZSetOperations1.size();
        if (platformsize.intValue() > recordSize) {
            boundZSetOperations1.removeRange(0, platformsize - recordSize);
            log.info("sendToRedis size:{} remove {} 0-{}",platformsize,keyCode,platformsize-recordSize);
        }
    }

    /**
     * 将消息转换为实体
     *
     * @param message 消息
     */
    public DataAddVO convertMessageToEntity(String message) {
        try {
            //创建ObjectMapper对象
            ObjectMapper objectMapper = new ObjectMapper();
            //将字符串转换为JSON对象
            JsonNode jsonNode = objectMapper.readTree(message);
            //将JSON对象转换为Java对象
            return objectMapper.treeToValue(jsonNode, DataAddVO.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }


    }
}
