package com.seer.teach.common.cache;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * SSE 数据缓存（Redis 版本）。
 * 以 sessionId 为 Key，List<Object> 为 Value。
 * 每个 SSE 会话缓存对应的推送数据。
 */
@Slf4j
@Component
public class SseDataCache {

    /** Redis key 前缀 */
    private static final String SSE_DATA_KEY_PREFIX = "sseData:";

    /** 每个会话缓存有效期（默认 30 分钟） */
    private static final Duration SSE_SESSION_TTL = Duration.ofMinutes(30);

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 获取 Redis 中完整的 SSE 数据列表。
     *
     * @param sessionId SSE 会话 ID
     * @return 数据列表（可能为空）
     */
    public List<Object> getAll(Integer sessionId) {
        String key = buildKey(sessionId);
        ListOperations<String, Object> ops = redisTemplate.opsForList();
        List<Object> list = ops.range(key, 0, -1);
        return list != null ? list : Collections.emptyList();
    }

    /**
     * 向 SSE 缓存中追加一条数据。
     *
     * @param sessionId SSE 会话 ID
     * @param data      SSE 数据对象
     */
    public void add(Integer sessionId, Object data) {
        String key = buildKey(sessionId);
        ListOperations<String, Object> ops = redisTemplate.opsForList();
        ops.rightPush(key, data);
        redisTemplate.expire(key, SSE_SESSION_TTL.toMillis(), TimeUnit.MILLISECONDS);
    }

    /**
     * 删除指定 SSE 会话的所有缓存数据。
     *
     * @param sessionId SSE 会话 ID
     */
    public void invalidate(Integer sessionId) {
        String key = buildKey(sessionId);
        redisTemplate.delete(key);
        log.debug("已清理 SSE 缓存: sessionId={}", sessionId);
    }

    /**
     * 判断指定 SSE 会话是否存在缓存数据。
     *
     * @param sessionId SSE 会话 ID
     * @return true=存在，false=不存在
     */
    public boolean exists(Integer sessionId) {
        String key = buildKey(sessionId);
        Boolean result = redisTemplate.hasKey(key);
        return Boolean.TRUE.equals(result);
    }

    /** 构建 Redis key */
    private String buildKey(Integer sessionId) {
        return SSE_DATA_KEY_PREFIX + sessionId;
    }
}
