public class WechatUtils {

    @Value("${wechat.appId:}")
    private String appId;

    @Value("${wechat.secret:}")
    private String secret;

    @Autowired
    private HttpCommonClientComponent client;

    @Autowired
    private IRedisService redisService;

    /***
     *
     * 获取签名
     * @param url
     * @return
     */
    public Map<String, Object> getWechatConfig(String url) {
        Long timestamp = System.currentTimeMillis();
        String nonceStr = getNonceString(32);
        String ticket = getJsapiTicket();
        String signature = DigestUtils.sha1Hex("jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url);

        Map<String, Object> mp = new HashMap<>();
        mp.put("appId", appId);
        mp.put("timestamp", timestamp);
        mp.put("nonceStr", nonceStr);
        mp.put("signature", signature);
        return mp;
    }

    private String getNonceString(Integer length) {
        String str = "zxcvbnmlkjhgfdsaqwertyuiopQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(str.charAt(random.nextInt(str.length())));
        }

        return sb.toString();
    }

    private String getJsapiTicket() {
        Object ticket = redisService.get(WechatConstant.BULL_WECHAT_SHARE_TICKET);
        if (!StringUtils.isEmpty(ticket)) {
            return ticket.toString();
        }

        String token = getAccessToken(true);
        String url = String.format(WechatConstant.JSAPI_TICKET_URL, token);
        String response = client.doHttpGetRequest(url, null);
        JSONObject result = JSONObject.parseObject(response);
        // 如果因为token的原因失败了 再尝试一次
        if (!StringUtils.isEmpty(result.get("errcode")) && "40001".equals(result.get("errcode").toString())) {
            token = getAccessToken(false);
            url = String.format(WechatConstant.JSAPI_TICKET_URL, token);
            response = client.doHttpGetRequest(url, null);
            result = JSONObject.parseObject(response);
        }
        if (!StringUtils.isEmpty(result.get("ticket")) && !StringUtils.isEmpty(result.get("expires_in"))) {
            String value = result.get("ticket").toString();
            long expiresIn = Long.parseLong(result.get("expires_in").toString());
            redisService.set(WechatConstant.BULL_WECHAT_SHARE_TICKET, value, expiresIn);
            return value;
        }

        return null;
    }

    /**
     * 获取access_token
     * @return
     */
    private String getAccessToken(Boolean getFromCache) {

        if (getFromCache) {
            Object token = redisService.get(WechatConstant.BULL_WECHAT_SHARE_TOKEN);
            if (!StringUtils.isEmpty(token)) {
                return token.toString();
            }
        }


        String url = WechatConstant.ACCESS_TOKEN_URL + "&appid=" + appId + "&secret=" + secret;
        String response = client.doHttpGetRequest(url, null);
        Map errorMap = JSONObject.parseObject(response, Map.class);
        if (errorMap.containsKey("errcode")) {
            log.info("{} 获取失败,appId:{}, secret: {}, error : {}", WechatConstant.ACCESS_TOKEN_URL, appId, secret, response);

        }
        JSONObject result = JSONObject.parseObject(response);
        if (!StringUtils.isEmpty(result.get("access_token")) && !StringUtils.isEmpty(result.get("expires_in"))) {
            String value = result.get("access_token").toString();
            long expiresIn = Long.parseLong(result.get("expires_in").toString());
            redisService.set(WechatConstant.BULL_WECHAT_SHARE_TOKEN, value, expiresIn);
            return value;
        }

        return null;
    }
}