package com.fs.common.core.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Redis 工具类
 * 提供对 Redis 各种数据结构的操作封装
 */
@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

/*    @Autowired
    private RedissonClient redissonClient;*/

    /**
     * 缓存基本对象
     *
     * @param key   缓存键
     * @param value 缓存值
     */
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 缓存基本对象（带过期时间）
     *
     * @param key      缓存键
     * @param value    缓存值
     * @param timeout  过期时间
     * @param timeUnit 时间单位
     */
    public void set(String key, Object value, long timeout, TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    /**
     * 获取缓存对象
     *
     * @param key 缓存键
     * @return 缓存值
     */
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 删除单个对象
     *
     * @param key 缓存键
     * @return 是否删除成功
     */
    public boolean delete(String key) {
        return Boolean.TRUE.equals(redisTemplate.delete(key));
    }

    /**
     * 删除多个对象
     *
     * @param keys 缓存键集合
     * @return 删除的对象数量
     */
    public long delete(Collection<String> keys) {
        return redisTemplate.delete(keys);
    }

    /**
     * 判断是否存在指定键
     *
     * @param key 缓存键
     * @return 是否存在
     */
    public boolean hasKey(String key) {
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }

    /**
     * 设置过期时间
     *
     * @param key     缓存键
     * @param timeout 过期时间
     * @param unit    时间单位
     * @return 是否设置成功
     */
    public boolean expire(String key, long timeout, TimeUnit unit) {
        return Boolean.TRUE.equals(redisTemplate.expire(key, timeout, unit));
    }

    /**
     * 获取过期时间
     *
     * @param key 缓存键
     * @return 剩余过期时间（秒）
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key);
    }

    // ======================== List 操作 ========================

    /**
     * 向列表右侧添加元素
     *
     * @param key   列表键
     * @param value 元素值
     * @return 列表长度
     */
    public long listRightPush(String key, Object value) {
        return redisTemplate.opsForList().rightPush(key, value);
    }

    /**
     * 向列表左侧弹出元素
     *
     * @param key 列表键
     * @return 元素值
     */
    public Object listLeftPop(String key) {
        return redisTemplate.opsForList().leftPop(key);
    }

    /**
     * 获取列表指定范围的元素
     *
     * @param key   列表键
     * @param start 起始位置
     * @param end   结束位置
     * @return 元素列表
     */
    public List<Object> listRange(String key, long start, long end) {
        return redisTemplate.opsForList().range(key, start, end);
    }

    // ======================== Set 操作 ========================

    /**
     * 向集合添加元素
     *
     * @param key    集合键
     * @param values 元素值
     * @return 添加成功的元素数量
     */
    public long setAdd(String key, Object... values) {
        return redisTemplate.opsForSet().add(key, values);
    }

    /**
     * 获取集合所有元素
     *
     * @param key 集合键
     * @return 元素集合
     */
    public Set<Object> setMembers(String key) {
        return redisTemplate.opsForSet().members(key);
    }

    /**
     * 判断元素是否在集合中
     *
     * @param key   集合键
     * @param value 元素值
     * @return 是否存在
     */
    public boolean setIsMember(String key, Object value) {
        return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(key, value));
    }

    // ======================== Hash 操作 ========================

    /**
     * 向哈希表中添加键值对
     *
     * @param key     哈希表键
     * @param hashKey 哈希键
     * @param value   哈希值
     */
    public void hashPut(String key, String hashKey, Object value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }

    /**
     * 向哈希表中添加键值对
     *
     * @param key     哈希表键
     * @param hashKey 哈希键
     */
    public void hashDelete(String key, String hashKey) {
        redisTemplate.opsForHash().delete(key, hashKey);
    }

    /**
     * 向哈希表中添加键值对批量
     *
     * @param key 哈希表键
     */
    public void hashPut(String key, Map<String, String> var2) {
        redisTemplate.opsForHash().putAll(key, var2);
    }

    /**
     * 获取哈希表中的值
     *
     * @param key     哈希表键
     * @param hashKey 哈希键
     * @return 哈希值
     */
    public Object hashGet(String key, String hashKey) {
        return redisTemplate.opsForHash().get(key, hashKey);
    }

    /**
     * 获取哈希表中所有键值对
     *
     * @param key 哈希表键
     * @return 键值对映射
     */
    public Map<Object, Object> hashEntries(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 获取哈希表中数量
     *
     * @param key 哈希表键
     * @return 键值对映射
     */
    public Long size(String key) {
        return redisTemplate.opsForHash().size(key);
    }

    // ======================== ZSet 操作 ========================

    /**
     * 向有序集合添加元素
     *
     * @param key   有序集合键
     * @param value 元素值
     * @param score 分数
     * @return 是否添加成功
     */
    public boolean zSetAdd(String key, Object value, double score) {
        return Boolean.TRUE.equals(redisTemplate.opsForZSet().add(key, value, score));
    }

    /**
     * 向有序集合删除元素
     *
     * @param key   有序集合键
     * @param value 数值
     * @return 是否添加成功
     */
    public void zSetRemove(String key,  Object value) {
       redisTemplate.opsForZSet().remove(key, value);
    }

    /**
     * 升序获取有序集合指定范围的元素
     *
     * @param key   有序集合键
     * @param start 起始位置
     * @param end   结束位置
     * @return 元素集合
     */
    public Set<Object> zSetRange(String key, long start, long end) {
        return redisTemplate.opsForZSet().range(key, start, end);
    }

    /**
     * 降序获取有序集合指定范围的元素
     *
     * @param key   有序集合键
     * @param start 起始位置
     * @param end   结束位置
     * @return 元素集合
     */
    public Set<Object> zSetReverseRange(String key, long start, long end) {
        return redisTemplate.opsForZSet().reverseRange(key, start, end);
    }

    /**
     * 获取有序集合元素数量
     *
     * @param key 有序集合键
     * @return 元素集合数量
     */
    public Long zSetSize(String key) {
        return redisTemplate.opsForZSet().size(key);
    }

    // ======================== 字符串专用操作 ========================

    /**
     * 设置字符串值
     *
     * @param key   键
     * @param value 值
     */
    public void setString(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    /**
     * 设置字符串值（带过期时间）
     *
     * @param key      键
     * @param value    值
     * @param timeout  过期时间
     * @param timeUnit 时间单位
     */
    public void setString(String key, String value, long timeout, TimeUnit timeUnit) {
        stringRedisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    /**
     * 获取字符串值
     *
     * @param key 键
     * @return 字符串值
     */
    public String getString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    /**
     * 获取字符串值
     *
     * @param key 键
     * @return 字符串值
     */
    public Long decrement(String key) {
        return stringRedisTemplate.opsForValue().decrement(key);
    }

    // ======================== 布隆过滤器 ========================

    // 获取布隆过滤器
/*    public RBloomFilter<String> getRBloomFilter(String key) {
        RBloomFilter<String> rBloomFilter = redissonClient.getBloomFilter(key);
        rBloomFilter.tryInit(100000L, 0.01);
        return rBloomFilter;
    }*/
}
