package com.bcxin.bi.common.util;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
import java.util.Map;

@Component
public class JwtUtil {

    /**
     * jwt秘钥 平台固定私钥
     */
    private static final String JWT_SECRET = "sdoDFyzfieqMrisd4H5o5t9weOl6GmSr";

    /**
     * millisecond 7天重新登录的时间间隔
     */
    private static final int JWT_REFRESH_TTL = 180*24*60*60*1000;

    /**
     * 由字符串生成加密key
     * @return
     */
    private static SecretKey generalKey(String stringKey){
        byte[] encodedKey = Base64.decodeBase64(stringKey);
        return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
    }

    /**
     * 创建jwt，ttlMillis为负数表示不过期
     * @param id
     * @param subject
     * @param ttlMillis
     * @return
     * @throws Exception
     */
    public static String createJWT(String id, String subject, String stringKey, long ttlMillis) throws Exception {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setSubject(subject)
                .signWith(signatureAlgorithm, generalKey(stringKey));
        if (ttlMillis >= 0) {
            long expMillis = System.currentTimeMillis() + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * 创建jwt
     * @param subject
     * @return
     */
    public static String createJWT(Map<String,String> subject) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        JwtBuilder builder = Jwts.builder()
//				.setId(JwtUtil.JWT_ID) // 暂时不用，减少流量
//				.setIssuedAt(new Date(System.currentTimeMillis())) //发行时间  暂时不用，减少流量
                .setSubject(JSON.toJSONString(subject)) //主题，就是附带在token中的信息
                .signWith(signatureAlgorithm, generalKey(JWT_SECRET)); //选择的算法，和私钥值
        if (JWT_REFRESH_TTL >= 0) { //如果过期时间为负数，那么不设置过期时间
            long expMillis = System.currentTimeMillis() + JWT_REFRESH_TTL;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * 创建jwt
     * @param subject
     * @return
     */
    public static String createJWT(Map<Object,Object> subject, String stringKey, long ttlMillis) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        JwtBuilder builder = Jwts.builder()
//				.setId(JwtUtil.JWT_ID) // 暂时不用，减少流量
//				.setIssuedAt(new Date(System.currentTimeMillis())) //发行时间  暂时不用，减少流量
                .setSubject(JSON.toJSONString(subject)) //主题，就是附带在token中的信息
                .signWith(signatureAlgorithm, generalKey(stringKey)); //选择的算法，和私钥值
        if (ttlMillis >= 0) { //如果过期时间为负数，那么不设置过期时间
            long expMillis = System.currentTimeMillis() + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * 解密jwt
     * @param jwttoken
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwttoken) {
        return Jwts.parser()
                .setSigningKey(generalKey(JWT_SECRET))
                .parseClaimsJws(jwttoken).getBody();
    }

    public static void main(String[] args)  {
        Claims c = parseJWT("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJET01BSU5JRFwiOlwiJydEYWlOSEdNaycnXCIsXCJ2aWV3Q29kZVwiOlwiSE5fVjVfUVlUU1wifSJ9.MyRLSAl5KfEev0VxuzTkKYdwjy1KUy5ubb7m3c7GLGI");
        /* 加密*/
        Map<String,String> param = Maps.newHashMap();
        //模拟参数1
        param.put("viewCode", "HN_V5_QYTS");
        param.put("DOMAINID", "'__QDtp16GVJR6hRa1vyVo'");
        //param.put("city", "'110100'");
        //加密生成token
        String token = JwtUtil.createJWT(param);
        Map<String, Object> requestMap = Maps.newHashMap();
        requestMap.put("token", token);

        System.out.println("企业：" + "http://visiblebi.test.bcxin.com.cn/view" + "?token=" + token);


        /* 加密*/
        Map<String,String> param2 = Maps.newHashMap();
        //模拟参数1
        param2.put("viewCode", "NN_BBD_JGTS");
        param2.put("DOMAINID", "");
        //加密生成token
        String token2 = JwtUtil.createJWT(param2);
        Map<String, Object> requestMap2 = Maps.newHashMap();
        requestMap2.put("token", token2);

        System.out.println("监管：" + "http://visiblebi.test.bcxin.com.cn/view" + "?token=" + token2);

    }

}
