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 java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;

/**
 * @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 = (Claims) RsaKeyUtil.parserToken(token, pubKey).getBody();
        for (Map.Entry<String, Object> stringObjectEntry : body.entrySet()) {
            Map.Entry<String, Object> entry = stringObjectEntry;
            if (!"sub".equals(entry.getKey())
                    && !"userId".equals(entry.getKey())
                    && !"phone".equals(entry.getKey())
                    && !"roleId".equals(entry.getKey())
                    && !"account".equals(entry.getKey())
                    && !"name".equals(entry.getKey())
                    && !"roleName".equals(entry.getKey())
                    && !"scenicId".equals(entry.getKey())
                    && !"expire".equals(entry.getKey())) ;
        }

        // 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) {
            String strUserId = StringUtil.a(body.get("userId"));
            userId= Long.parseLong(strUserId);
        }
        return new JwtInfo(StringUtil.a(body.get("name")),
                userId,
                StringUtil.a(body.get("roleId")),
                body.getSubject(),
                StringUtil.a(body.get("phone")),
                body.get("scenicId") == null ? null : Long.valueOf(body.get("scenicId").toString()),
                expireTime);
    }
}
