package com.arms.api.util.redisrepo;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Set;

@Component
public class RedisZSetCommand {

    private final RedisTemplate<String, Object> redisTemplate;

    public RedisZSetCommand(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    // ── 저장 ──

    /**
     * ZSet에 멤버와 score를 추가 (ZADD)
     * score가 클수록 높은 순위 (reverseRange 시 먼저 반환)
     */
    public Boolean add(String key, Object value, double score) {
        return redisTemplate.opsForZSet().add(key, value, score);
    }

    /**
     * ZSet에 멤버가 없을 때만 추가 (ZADD NX)
     */
    public Boolean addIfAbsent(String key, Object value, double score) {
        return redisTemplate.opsForZSet().addIfAbsent(key, value, score);
    }

    // ── 조회 ──

    /**
     * score 오름차순으로 범위 조회 (ZRANGE)
     * start=0, end=-1 이면 전체 조회
     */
    public Set<Object> range(String key, long start, long end) {
        return redisTemplate.opsForZSet().range(key, start, end);
    }

    /**
     * score 내림차순으로 범위 조회 (ZREVRANGE)
     * 최신순 목록 조회에 사용 (score = timestamp)
     */
    public Set<Object> reverseRange(String key, long start, long end) {
        return redisTemplate.opsForZSet().reverseRange(key, start, end);
    }

    /**
     * score 범위로 멤버 조회 오름차순 (ZRANGEBYSCORE)
     */
    public Set<Object> rangeByScore(String key, double min, double max) {
        return redisTemplate.opsForZSet().rangeByScore(key, min, max);
    }

    /**
     * score 범위로 멤버 조회 내림차순 (ZREVRANGEBYSCORE)
     */
    public Set<Object> reverseRangeByScore(String key, double min, double max) {
        return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max);
    }

    /**
     * ZSet의 멤버 수 조회 (ZCARD)
     */
    public Long size(String key) {
        return redisTemplate.opsForZSet().size(key);
    }

    /**
     * 특정 멤버의 score 조회 (ZSCORE)
     */
    public Double score(String key, Object value) {
        return redisTemplate.opsForZSet().score(key, value);
    }

    /**
     * 특정 멤버의 오름차순 순위 조회 (ZRANK)
     * 0부터 시작
     */
    public Long rank(String key, Object value) {
        return redisTemplate.opsForZSet().rank(key, value);
    }

    /**
     * 특정 멤버의 내림차순 순위 조회 (ZREVRANK)
     * 0부터 시작
     */
    public Long reverseRank(String key, Object value) {
        return redisTemplate.opsForZSet().reverseRank(key, value);
    }

    // ── 삭제 ──

    /**
     * ZSet에서 멤버 삭제 (ZREM)
     */
    public Long remove(String key, Object... values) {
        return redisTemplate.opsForZSet().remove(key, values);
    }

    /**
     * 오름차순 순위 범위로 멤버 삭제 (ZREMRANGEBYRANK)
     */
    public Long removeRange(String key, long start, long end) {
        return redisTemplate.opsForZSet().removeRange(key, start, end);
    }

    /**
     * score 범위로 멤버 삭제 (ZREMRANGEBYSCORE)
     */
    public Long removeRangeByScore(String key, double min, double max) {
        return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
    }

    // ── 증감 ──

    /**
     * 특정 멤버의 score를 증가 (ZINCRBY)
     */
    public Double incrementScore(String key, Object value, double delta) {
        return redisTemplate.opsForZSet().incrementScore(key, value, delta);
    }

}
