package com.ai.da.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class RedisUtil {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    public Boolean hasKey(String key){
        return redisTemplate.hasKey(key);
    }

    //- - - - - - - - - - - - - - - - - - - - -  ZSet类型 - - - - - - - - - - - - - - - - - - - -

    /**
     * 向ZSet中添加元素
     */
    public void addToZSet(String key, String value, Double score) {
        redisTemplate.opsForZSet().add(key, value, score);
    }

    /**
     * 从ZSet中删除元素
     */
    public void removeFromZSet(String key, String value) {
        redisTemplate.opsForZSet().remove(key, value);
    }

    /**
     * 获取指定元素的当前排列顺序
     */
    public Long getRank(String key, String value) {
        return redisTemplate.opsForZSet().rank(key, value);
    }

    /**
     * 获取当前ZSet中的最大score
     */
    public Double getMaxScore(String key) {
        Set<ZSetOperations.TypedTuple<String>> set = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, 0);

        if (!CollectionUtils.isEmpty(set)) {
            Double score = set.iterator().next().getScore();
            return score + 1.0;
        } else {
            return 1.0;
        }
    }

    /**
     * 判断元素是否存在
     */
    public Boolean isElementExistsInZSet(String key, String value) {
        return redisTemplate.opsForZSet().score(key, value) != null;
    }

    /**
     * 获取当前ZSet中数据量的总和
     */
    public Long getZSetTotalCount(String key) {
        return redisTemplate.opsForZSet().zCard(key);
    }


    public Set<String> getZSetTotalData(String key){
        return redisTemplate.opsForZSet().range(key, 0, -1);
    }

    //- - - - - - - - - - - - - - - - - - - - -  set类型 - - - - - - - - - - - - - - - - - - - -

    /**
     * 将数据放入set缓存
     */
    public void addToSet(String key, String value) {
        redisTemplate.opsForSet().add(key, value);
    }

    /**
     * 弹出变量中的元素
     */
    public void removeFromSet(String key, String value) {
        redisTemplate.opsForSet().remove(key, value);
    }

    /**
     * 检查给定的元素是否在变量中。
     */
    public Boolean isElementExistsInSet(String key, String obj) {
        return redisTemplate.opsForSet().isMember(key, obj);
    }


    //- - - - - - - - - - - - - - - - - - - - -  hash类型 - - - - - - - - - - - - - - - - - - - -

    /**
     * 加入缓存
     */
    public void addToMap(String key, Map<String, String> map) {
        redisTemplate.opsForHash().putAll(key, map);
    }

    /**
     * 验证指定 key 下 有没有指定的 hashkey
     */
    public Boolean isElementExistsInMap(String key, String hashKey) {
        return redisTemplate.opsForHash().hasKey(key, hashKey);
    }

    /**
     * 获取指定key的值string
     */
    public String getMapValue(String key1, String key2) {
        return String.valueOf(redisTemplate.opsForHash().get(key1, key2));
    }

    /**
     * 删除指定 hash 的 HashKey
     *
     * @return 删除成功的 数量
     */
    public Long removeFromMap(String key, String hashKeys) {
        return redisTemplate.opsForHash().delete(key, hashKeys);
    }

    //- - - - - - - - - - - - - - - - - - - - -  String类型 - - - - - - - - - - - - - - - - - - - -
    public void addToString(String key, String value){
        redisTemplate.opsForValue().set(key,value);
    }

    public void addToString(String key, String value, Long expiresIn){
        redisTemplate.opsForValue().set(key,value,expiresIn, TimeUnit.SECONDS);
    }

    public String getFromString(String key){
        return redisTemplate.opsForValue().get(key);
    }

    public Set<String> getKeysFromString(String key){
        return redisTemplate.keys(key);
    }

    public List<String> getMultiValue(Set<String> keys){
        return redisTemplate.opsForValue().multiGet(keys);
    }

    public Long getExpire(String key){
        return redisTemplate.getExpire(key);
    }

    public void removeFromString(String key){
        redisTemplate.delete(key);
    }

}
