package com.hzya.frame.cbs8.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.hzya.frame.web.action.ApplicationContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.relational.core.sql.In;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description cbs token
 * @Author xiangerlin
 * @Date 2024/6/7 15:56
 **/
@Component
public class CbsAccessToken {

    private static final Logger logger = LoggerFactory.getLogger(CbsAccessToken.class);
    @Value("${cbs8.appId:}")
    private  String app_id;
    @Value("${cbs8.appSecret:}")
    private  String app_secret;
    @Value("${cbs8.url:}")
    private  String app_url;

    private static String appId;
    private static String appSecret;
    private static String url;
    @PostConstruct
    public void init() {
        appId = app_id;
        appSecret = app_secret;
        url = app_url;
    }
    //刷新token用
    private static final String BEARER = "Bearer ";
    /**
     * 过期时间
     */
    private Long expiryTime ;
    private String token;

    private CbsAccessToken(){

    }
    private static CbsAccessToken cbsAccessToken = new CbsAccessToken();


    public static CbsAccessToken getInstance() {
        if (null == cbsAccessToken.token){
            initToken();
        }else {
            //判断token有没有过期
            if (System.currentTimeMillis() >= cbsAccessToken.expiryTime){
                initToken();
            }else {
                refreshToken();
            }
        }
        return cbsAccessToken;
    }

    public static String getToken(){
        return getInstance().token;
    }
    /**
     * 获取token
     */
    private static void initToken(){
        CbsAccessToken ct = (CbsAccessToken) ApplicationContextUtil.getBeanByName("cbsAccessToken");
        logger.info("开始获取cbstoken");
        Map<String,String> param = new HashMap<>();
        param.put("app_id",ct.appId);
        param.put("app_secret",ct.appSecret);
        param.put("grant_type","client_credentials");
        String res = HttpRequest.post(ct.url+"/openapi/app/v1/app/token").body(JSONObject.toJSONString(param)).execute().body();
        logger.info("获取cbstoken结果",res);
        if (StrUtil.isNotEmpty(res) && JSONUtil.isTypeJSON(res)){
            JSONObject tokenObject =  JSONObject.parseObject(res);
            String code = tokenObject.getString("code");//0表示成功
            if ("0".equals(code)){
                JSONObject dataObj = tokenObject.getJSONObject("data");
                if (null != dataObj){
                    String token = dataObj.getString("token");
                    //过期时间 单位是秒 30分钟有效
                    Integer expires = dataObj.getInteger("expires");
                    cbsAccessToken.token = token;
                    //提前5分钟让token失效 所以这里设置成过期时间为当前时间+25分钟
                    cbsAccessToken.expiryTime = System.currentTimeMillis()+1000*60*25L;
                }
            }
        }
    }

    /**
     * 刷新token
     */
    private static void refreshToken(){
        CbsAccessToken ct = (CbsAccessToken) ApplicationContextUtil.getBeanByName("cbsAccessToken");
        //token不为空，并且没过期 刷新token
        if (null != cbsAccessToken.token && System.currentTimeMillis() < cbsAccessToken.expiryTime ){
            String res = HttpRequest.get(ct.url + "/openapi/app/v1/app/refresh-token").header("Authorization", BEARER + cbsAccessToken.token).execute().body();
            logger.info("刷新cbstoken结果",res);
            if (StrUtil.isNotEmpty(res) && JSONUtil.isTypeJSON(res)){
                JSONObject tokenObject =  JSONObject.parseObject(res);
                String code = tokenObject.getString("code");//0表示成功
                if ("0".equals(code)){
                    JSONObject dataObj = tokenObject.getJSONObject("data");
                    if (null != dataObj){
                        //续期的token
                        String token = dataObj.getString("token");
                        //新token过期时间 单位是秒 30分钟有效
                        Integer expires = dataObj.getInteger("expires");
                        cbsAccessToken.token = token;
                        //提前5分钟让token失效 所以这里设置成过期时间为当前时间+25分钟
                        cbsAccessToken.expiryTime = System.currentTimeMillis()+1000*60*25L;
                    }
                }else {
                    initToken();
                }
            }
        }else {
            initToken();
        }
    }

    public static void main(String[] args) {
        System.out.println("第1次取token："+getToken());
        System.out.println("第2次取token："+getToken());
        System.out.println("第3次取token："+getToken());
    }
}
