package com.pharmacopoeia.security;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import com.pharmacopoeia.config.JwtProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;

@Component
public class JwtUtil {

    private static final Logger log = LoggerFactory.getLogger(JwtUtil.class);

    private final JwtProperties jwtProperties;
    private final SecretKey key;

    public JwtUtil(JwtProperties jwtProperties) {
        this.jwtProperties = jwtProperties;
        this.key = Keys.hmacShaKeyFor(jwtProperties.getSecret().getBytes(StandardCharsets.UTF_8));
    }

    public String createToken(String subject) {
        String token = Jwts.builder()
                .subject(subject)
                .issuedAt(new Date())
                .expiration(new Date(System.currentTimeMillis() + jwtProperties.getExpiration()))
                .signWith(key)
                .compact();
        log.info("JWT 创建成功: subject={}, expires={}", subject,
                new Date(System.currentTimeMillis() + jwtProperties.getExpiration()));
        return token;
    }

    public Claims parseToken(String token) {
        Claims claims = Jwts.parser()
                .verifyWith(key)
                .build()
                .parseSignedClaims(token)
                .getPayload();
        log.debug("JWT 解析成功: subject={}, issuedAt={}, expires={}",
                claims.getSubject(), claims.getIssuedAt(), claims.getExpiration());
        return claims;
    }

    public boolean validateToken(String token) {
        try {
            Claims claims = parseToken(token);
            log.debug("JWT 验证通过: subject={}", claims.getSubject());
            return true;
        } catch (ExpiredJwtException e) {
            log.warn("JWT 已过期: {}", e.getMessage());
            return false;
        } catch (JwtException | IllegalArgumentException e) {
            log.warn("JWT 验证失败: {}", e.getMessage());
            return false;
        }
    }

    public String getSubject(String token) {
        return parseToken(token).getSubject();
    }
}