package com.ruoyi.common.utils;

import com.alibaba.fastjson2.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.Verification;
import com.ruoyi.common.constant.AppUserLeaderEnum;
import com.ruoyi.common.constant.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Slf4j
public class JWTUtil {
    //自己的密钥
//    private static final String SING = "!QsfhisllR";

    /**
     * 生成token header payload sign
     */
    public static String getToken(Map<String, String> map, String secreKey) {
        Calendar instance = Calendar.getInstance();
        // 七天后过期
        instance.add(Calendar.DAY_OF_YEAR, 7);
        //创建jwtbuilder
        JWTCreator.Builder builder = JWT.create();
        map.forEach((k, v) -> {
            builder.withClaim(k, v);
        });
        //设置过期时间
        String token = builder.withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256(secreKey)); //sign
        return token;
    }

    /**
     * 验证token 合法性
     *
     * @param token
     */
    public static DecodedJWT verify(String token, String secretKey) {
        Algorithm hmac256 = Algorithm.HMAC256(secretKey);
//        log.info("【验证Token】hmac256：{}", JSON.toJSONString(hmac256));

        Verification require = JWT.require(hmac256);
//        log.info("【验证Token】require：{}", JSON.toJSONString(require));

        JWTVerifier build = require.build();
//        log.info("【验证Token】build：{}", JSON.toJSONString(build));

        DecodedJWT verify = build.verify(token);
        log.info("【验证Token】verify：{}", JSON.toJSONString(verify));

        return verify;
//        return JWT.require(Algorithm.HMAC256(secretKey)).build().verify(token);
    }

    public static String getRequestToken() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        return request.getHeader(Constants.TOKEN);
    }

    /**
     * APP用户表ID（tb_app_login.id bigint）
     *
     * @return
     */
    public static String getUserId() {
        String requestToken = getRequestToken();
        DecodedJWT jwt = JWT.decode(requestToken);
        return jwt.getClaim("id").asString();
    }

    /**
     * WEB用户表ID（sys_user.user_id bigint）
     *
     * @return
     */
    public static String getPCUserId() {
        String requestToken = getRequestToken();
        DecodedJWT jwt = JWT.decode(requestToken);
        Claim pcUserId = jwt.getClaim("pcUserId");
        if (pcUserId != null) {
            return pcUserId.asString();
        }
        return null;
    }

    /**
     * 承包商用户表ID（tb_contractor_user.id varchar(36)）
     *
     * @return
     */
    public static String getContractorUserId() {
        String requestToken = getRequestToken();
        DecodedJWT jwt = JWT.decode(requestToken);
        Claim contractorUserId = jwt.getClaim("contractorUserId");
        if (contractorUserId != null) {
            return contractorUserId.asString();
        }
        return null;
    }

    /**
     * APP用户类型：1内部，2承包商
     * AppUserTypeEnum
     *
     * @return
     */
    public static String getAppUserType() {
        String requestToken = getRequestToken();
        DecodedJWT jwt = JWT.decode(requestToken);
        return jwt.getClaim("userType").asString();
    }

    /**
     * 是否领导：
     * AppUserLeaderEnum.LEADER
     * LEADER("领导","10"),
     * EMPLOYEES("员工（申请人、审核人）","20");
     *
     * @return
     */
    public static boolean isLeader() {
        try {
            String requestToken = getRequestToken();
            DecodedJWT jwt = JWT.decode(requestToken);
            String leader = jwt.getClaim("leader").asString();
            if (AppUserLeaderEnum.LEADER.getValue().equals(leader)) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 查询当前登录人的岗位ID集合
     *
     * @return
     */
    public static List<Long> getPostIdList() {
        List<Long> postIdList = new ArrayList<>();
        try {
            String requestToken = getRequestToken();
            DecodedJWT jwt = JWT.decode(requestToken);
            String postIdListJoin = jwt.getClaim("postIdList").asString();
            if (StringUtils.isNotBlank(postIdListJoin)) {
                String[] postIdArr = postIdListJoin.split(",");
                for (String postId : postIdArr) {
                    postIdList.add(Long.parseLong(postId));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return postIdList;
    }


 /*   public static String getUri(String token) {
        DecodedJWT jwt = JWT.decode(token);
        return jwt.getClaim("uri").asString();
    }*/

    public static String getCompanyCode() {
        String requestToken = getRequestToken();
        DecodedJWT jwt = JWT.decode(requestToken);
        return jwt.getClaim("companyCode").asString();
    }

    /**
     * APP用户表企业编码
     *
     * @return
     */
    public static String getUserName() {
        String requestToken = getRequestToken();
        DecodedJWT jwt = JWT.decode(requestToken);
        return jwt.getClaim("userName").asString();
    }

    /**
     * 用户昵称：内部用户时是系统用户昵称、承包商用户时是承包用户表姓名
     *
     * @return
     */
    public static String getNickName() {
        String requestToken = getRequestToken();
        DecodedJWT jwt = JWT.decode(requestToken);
        return jwt.getClaim("nickName").asString();
    }


    public static void main(String[] args) {
        /*DecodedJWT jwt = JWT.decode("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiMTExMSIsImlkIjoiMyIsImV4cCI6MTY4MjgxNjg3M30.NMRHU6sT8L_JRBK6zocac92SegM-YKJ6_YG0M2FPyLQ");
        String name =  jwt.getClaim("id").asString();
        System.out.println(name);*/
        Map<String, String> map = new HashMap<>();
        map.put("id", "1");
        //map.put("uri","/order/createOrder");
        map.put("uri", "/order/orderList");
        System.out.println(getToken(map, "WgSvEvZe"));
    }

}
