package com.seer.teach.common.cache;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.seer.teach.common.cache.dto.UserStudyStatusDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用户学习状态缓存
 * @author Captain
 * @since 2025-10-12
 */
@Slf4j
@Component
public class UserStudyStatusCache {

    /** Redis Key 前缀 */
    private static final String REDIS_PREFIX = "studyStatus:";

    /** 默认过期时间（1小时） */
    private static final Duration DEFAULT_TTL = Duration.ofHours(1);

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private static final ObjectMapper MAPPER = new ObjectMapper();

    /** 保存用户学习状态（自动过期1小时） */
    public void put(Integer userId, UserStudyStatusDTO status) {
        if (userId == null || status == null) return;

        try {
            String key = REDIS_PREFIX + userId;
            String json = MAPPER.writeValueAsString(status);
            redisTemplate.opsForValue().set(key, json, DEFAULT_TTL);
            log.debug("[UserStudyStatusCache] 保存学习状态 userId={}, value={}", userId, json);
        } catch (JsonProcessingException e) {
            log.error("[UserStudyStatusCache] JSON 序列化失败 userId={}, error={}", userId, e.getMessage());
        }
    }

    /** 获取用户学习状态 */
    public UserStudyStatusDTO get(Integer userId) {
        if (userId == null) return null;

        String key = REDIS_PREFIX + userId;
        Object json = redisTemplate.opsForValue().get(key);
        if (json == null) return null;

        try {
            return MAPPER.readValue(json.toString(), UserStudyStatusDTO.class);
        } catch (Exception e) {
            log.warn("[UserStudyStatusCache] JSON 解析失败 userId={}, json={}", userId, json);
            return null;
        }
    }

    /** 删除用户学习状态 */
    public void remove(Integer userId) {
        if (userId == null) return;
        redisTemplate.delete(REDIS_PREFIX + userId);
        log.debug("[UserStudyStatusCache] 删除学习状态 userId={}", userId);
    }

    /** 判断用户是否存在学习状态 */
    public boolean exists(Integer userId) {
        if (userId == null) return false;
        return Boolean.TRUE.equals(redisTemplate.hasKey(REDIS_PREFIX + userId));
    }

    /** 获取所有用户学习状态（仅限小规模使用） */
    public Map<Integer, UserStudyStatusDTO> getAll() {
        // 注意：若用户数较多，请避免 keys("*")，应维护用户ID列表
        Map<Integer, UserStudyStatusDTO> result = new ConcurrentHashMap<>();
        for (String key : redisTemplate.keys(REDIS_PREFIX + "*")) {
            try {
                String json = (String) redisTemplate.opsForValue().get(key);
                if (json != null) {
                    Integer userId = Integer.parseInt(key.substring(REDIS_PREFIX.length()));
                    result.put(userId, MAPPER.readValue(json, UserStudyStatusDTO.class));
                }
            } catch (Exception ignored) {}
        }
        return result;
    }

    /** 清空所有学习状态（慎用） */
    public void clearAll() {
        for (String key : redisTemplate.keys(REDIS_PREFIX + "*")) {
            redisTemplate.delete(key);
        }
        log.warn("[UserStudyStatusCache] 已清空所有学习状态");
    }
}
