package com.seer.teach.common.cache;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * User SSE 缓存 Service 层
 * <p>
 * 作用：
 * - 统一封装 UserSseCache 的操作
 * - 业务层调用时，不直接依赖 UserSseCache 工具类
 * - 方便后续扩展（例如埋点统计、AOP日志等）
 * <p>
 * 用法示例：
 * userSseCacheService.saveSession("SSE_CHAT:", userId, sessionId);
 * Integer session = userSseCacheService.getSession("SSE_CHAT:", userId);
 *
 * @author Captain
 * @since 2025-09-28
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SseLifeCycleCacheService {

    /**
     * AI聊天Redis键前缀
     */
    public static final String AI_CHAT_REDIS_KEY_PREFIX = "sseChatLifeCycle:";

    /**
     * AI批改Redis键前缀
     */
    public static final String AI_CORRECT_REDIS_KEY_PREFIX = "sseCorrectLifeCycle:";

    /**
     * AI学习Redis键前缀
     */
    public static final String AI_STUDY_REDIS_KEY_PREFIX = "sseStudyLifeCycle:";

    private final SseLifeCycleCache sseLifeCycleCache;

    /**
     * 获取用户的 SSE 缓存值（优先 L1 -> L2）
     *
     * @param prefix Redis Key 前缀
     * @param userId 用户 ID
     * @return 缓存值（可能为 null）
     */
    public Integer getSession(String prefix, Integer userId) {
        return sseLifeCycleCache.get(prefix, userId);
    }

    /**
     * 保存用户 SSE 缓存（先写 L2 -> 再写 L1）
     *
     * @param prefix    Redis Key 前缀
     * @param userId    用户 ID
     * @param sessionId 会话 ID
     */
    public void saveSession(String prefix, Integer userId, Integer sessionId) {
        sseLifeCycleCache.put(prefix, userId, sessionId);
    }

    /**
     * 删除用户 SSE 缓存（双删：L1 + L2）
     *
     * @param prefix Redis Key 前缀
     * @param userId 用户 ID
     */
    public void removeSession(String prefix, Integer userId) {
        sseLifeCycleCache.invalidate(prefix, userId);
    }

    /**
     * 仅查 Redis (L2)
     */
    public Integer peekRedis(String prefix, Integer userId) {
        return sseLifeCycleCache.peekL2(prefix, userId);
    }

    /**
     * 仅查本地缓存 (L1)
     */
    public Integer peekLocal(String prefix, Integer userId) {
        return sseLifeCycleCache.peekL1(prefix, userId);
    }
}
