package com.ycwl.basic.utils;


import com.ycwl.basic.model.jwt.JwtInfo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;
import java.util.Objects;

/**
 * @author yangchen
 */
public class JwtAnalysisUtil {

    /**
     * 生成 Token
     *
     * @param jwtInfo
     * @param priKey
     * @param expireTime
     * @return
     * @throws Exception
     */
    public static String generateToken(JwtInfo jwtInfo, byte[] priKey, LocalDateTime expireTime) throws Exception {
        JwtBuilder builder = Jwts.builder().setSubject(jwtInfo.getAccount())
                .claim("userId", jwtInfo.getUserId())
                .claim("roleId", jwtInfo.getRoleId())
                .claim("phone", jwtInfo.getPhone())
                .claim("name", jwtInfo.getName())
                // 返回从1970 00：00：00 到现在的毫秒差（实际的过期时间）
                .claim("expire", expireTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        return builder.signWith(SignatureAlgorithm.RS256, RsaKeyUtil.getPrivateKey(priKey)).compact();
    }

    /**
     * 解析 Token
     *
     * @param token
     * @param pubKey
     * @return
     * @throws Exception
     */
    public static JwtInfo getInfoFromToken(String token, byte[] pubKey) throws Exception {
        Claims body = RsaKeyUtil.parserToken(token, pubKey).getBody();

        // convert
        LocalDateTime expireTime = null;
        try {
            // expire time
            Object expire = body.get("expire");
            if (expire != null) {
                expireTime = LocalDateTime.ofInstant(Instant.ofEpochMilli((Long) expire), ZoneId.systemDefault());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Long userId = null;
        if (body.get("userId")!=null) {
            userId= Long.parseLong(Objects.requireNonNullElse(body.get("userId"), "").toString());
        }
        return new JwtInfo(Objects.requireNonNullElse(body.get("name"), "").toString(),
                userId,
                Objects.requireNonNullElse(body.get("roleId"), "").toString(),
                body.getSubject(),
                Objects.requireNonNullElse(body.get("phone"), "").toString(),
                expireTime);
    }
}
