package top.awinx.stu01.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import top.awinx.stu01.config.JwtConfig;
import top.awinx.stu01.entity.SysUser;

import javax.crypto.SecretKey;
import java.util.Date;

/**
 * JWT工具类（适配jjwt 0.13.0）
 * 功能：生成token、解析token、校验token
 */
@Component
public class JwtUtil {

    @Resource
    private JwtConfig jwtConfig;

    /**
     * 生成JWT令牌
     * @param sysUser 登录成功的用户信息
     * @return token字符串
     */
    public String generateToken(SysUser sysUser) {
        // 生成密钥（适配jjwt 0.13.0，需32位密钥）
        SecretKey secretKey = jwtConfig.jwtSecretKey();
        
        // 构建token，载荷包含user_id、user_type、username
        return Jwts.builder()
                .claim("user_id", sysUser.getId()) // 用户ID
                .claim("user_type", sysUser.getUserType()) // 用户类型（1-学生/2-教师/3-管理员）
                .claim("username", sysUser.getUsername()) // 用户名
                .issuedAt(new Date()) // 签发时间
                .expiration(new Date(System.currentTimeMillis() + jwtConfig.getExpire() * 1000)) // 过期时间
                .signWith(secretKey) // 签名
                .compact();
    }

    /**
     * 解析token，获取载荷信息
     * @param token JWT令牌
     * @return 载荷Claims
     */
    public Claims parseToken(String token) {
        SecretKey secretKey = jwtConfig.jwtSecretKey();
        return Jwts.parser()
                .verifyWith(secretKey)
                .build()
                .parseSignedClaims(token)
                .getPayload();
    }

    /**
     * 获取token中的用户信息
     * @param token
     * @return 用户信息
     */
    public SysUser getUserFromToken(String token) {
        Claims claims = parseToken(token);
        SysUser sysUser = new SysUser();
        sysUser.setId(claims.get("user_id", Integer.class));
        sysUser.setUserType(claims.get("user_type", Integer.class));
        sysUser.setUsername(claims.get("username", String.class));
        return sysUser;
    }

    /**
     * 校验token是否合法（未过期+签名正确）
     * @param token JWT令牌
     * @return true-合法，false-非法
     */
    public boolean validateToken(String token) {
        try {
            Claims claims = parseToken(token);
            // 校验是否过期
            return !claims.getExpiration().before(new Date());
        } catch (Exception e) {
            // 签名错误、过期、格式错误等均返回false
            return false;
        }
    }
}
