package org.lingniu.idp.service.core.login;

import lombok.extern.slf4j.Slf4j;
import org.lingniu.idp.common.redis.RedisCache;
import org.lingniu.idp.constant.CacheConstants;
import org.lingniu.idp.model.vo.RefreshTokenInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.util.Map;

@Component
@Slf4j
public class RedisRefreshTokenService {
    
    @Autowired
    private RedisCache redisCache;
    
    private final long REFRESH_TOKEN_EXPIRE = 30 * 24 * 3600L; // 30天
    
    /**
     * 存储Refresh Token到Redis Hash
     */
    public void storeRefreshToken(RefreshTokenInfo tokenInfo) {
        String key = String.format(CacheConstants.REFRESH_TOKEN_KEY, tokenInfo.getTokenValue());
        
        redisCache.setCacheMap(key,tokenInfo.toMap());
        Instant expiresAt = tokenInfo.getExpiresAt();
        long expire = REFRESH_TOKEN_EXPIRE;
        if(expiresAt!=null){
            expire = expiresAt.getEpochSecond() - Instant.now().getEpochSecond();
        }

        redisCache.expire(key,expire);
        // 维护用户会话列表
        String userSessionsKey = String.format(CacheConstants.USER_SESSIONS, tokenInfo.getUserId());
        redisCache.setCacheSet(userSessionsKey,tokenInfo.getTokenValue());
        redisCache.expire(userSessionsKey,expire);
    }
    
    /**
     * 获取Refresh Token信息
     */
    public RefreshTokenInfo getRefreshTokenInfo(String token) {
        String key = String.format(CacheConstants.REFRESH_TOKEN_KEY, token);
        Map<String, Object> cacheMap = redisCache.getCacheMap(key);
        if(cacheMap!=null){
            return RefreshTokenInfo.fromMap(cacheMap);
        }
        return null;
    }
    
    /**
     * 更新Refresh Token最后使用时间
     */
    public void updateRefreshToken(RefreshTokenInfo tokenInfo) {
        String key = String.format(CacheConstants.REFRESH_TOKEN_KEY, tokenInfo.getTokenValue());
        redisCache.setCacheMap(key,tokenInfo.toUpdateMap());
    }

    /**
     * 作废 不删除
     * @param tokenInfo
     */
    public void revokeRefreshToken(RefreshTokenInfo tokenInfo) {
        String key = String.format(CacheConstants.REFRESH_TOKEN_KEY, tokenInfo.getTokenValue());
        String userSessionsKey = String.format(CacheConstants.USER_SESSIONS, tokenInfo.getUserId());
        redisCache.deleteCacheSetValue(userSessionsKey,tokenInfo.getTokenValue());
        redisCache.setCacheMap(key,tokenInfo.toRevokeMap());
    }
}