package org.lingniu.sdk.model.token;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

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

/**
 * Access Token 信息
 * 存储在 Redis String 结构中
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AccessTokenInfo {
    private String tokenValue;
    
    /**
     * 用户名
     */
    private String username;

    
    /**
     * 颁发时间
     */
    private Instant issuedAt;
    
    /**
     * 过期时间
     */
    private Instant expiresAt;

    /**
     * 关联的刷新Token ID
     */
    private String refreshTokenId;
    
    /**
     * JWT ID（如果是JWT token）
     */
    private String jti;
    
    /**
     * 附加数据（JSON格式）
     */
    private String additionalInfo;

    private String clientRegistrationId;
    
    /**
     * 检查Token是否过期
     */
    public boolean isExpired() {
        return expiresAt != null && Instant.now().isAfter(expiresAt);
    }
    
    /**
     * 检查Token是否有效
     */
    public boolean isValid() {
        return !isExpired();
    }
    
    /**
     * 获取剩余有效时间（秒）
     */
    public long getRemainingSeconds() {
        if (expiresAt == null) {
            return 0;
        }
        Instant now = Instant.now();
        if (now.isAfter(expiresAt)) {
            return 0;
        }
        return expiresAt.getEpochSecond() - now.getEpochSecond();
    }
    
    /**
     * 获取Token使用时长（秒）
     */
    public long getUsedSeconds() {
        if (issuedAt == null) {
            return 0;
        }
        Instant end = Instant.now();
        return end.getEpochSecond() - issuedAt.getEpochSecond();
    }

    /**
     * 转换为Map，便于Redis存储
     */
    public Map<String, Object> toMap() {
        Map<String, Object> map = new HashMap<>();
        map.put("username", username);
        map.put("tokenValue",tokenValue);
        map.put("issuedAt", issuedAt != null ? issuedAt.toString() : null);
        map.put("expiresAt", expiresAt != null ? expiresAt.toString() : null);
        map.put("refreshTokenId", refreshTokenId);
        map.put("jti", jti);
        map.put("clientRegistrationId",clientRegistrationId);
        map.put("additionalInfo", additionalInfo);
        return map;
    }
    
    /**
     * 从Map创建AccessTokenInfo
     */
    public static AccessTokenInfo fromMap(Map<String, Object> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        
        AccessTokenInfo.AccessTokenInfoBuilder builder = AccessTokenInfo.builder();
        builder.username((String) map.get("username"));
        builder.tokenValue((String) map.get("tokenValue"));
        // 处理时间字段
        String issuedAtStr = (String) map.get("issuedAt");
        if (issuedAtStr != null) {
            builder.issuedAt(Instant.parse(issuedAtStr));
        }
        
        String expiresAtStr = (String) map.get("expiresAt");
        if (expiresAtStr != null) {
            builder.expiresAt(Instant.parse(expiresAtStr));
        }
        
        builder.refreshTokenId((String) map.get("refreshTokenId"));
        builder.jti((String) map.get("jti"));
        builder.clientRegistrationId((String) map.get("clientRegistrationId"));
        builder.additionalInfo((String) map.get("additionalInfo"));
        
        return builder.build();
    }
    
    /**
     * 简化的用户信息（用于接口返回）
     */
    public Map<String, Object> toSimpleInfo() {
        Map<String, Object> info = new HashMap<>();
        info.put("username", username);
        info.put("expiresAt", expiresAt != null ? expiresAt.toEpochMilli() : null);
        info.put("issuedAt", issuedAt != null ? issuedAt.toEpochMilli() : null);
        info.put("valid", isValid());
        return info;
    }
}