package com.jfinal.club.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * @descriptions:
 * @author: lc
 * @date: 2020-08-22 12:27:41
 * @Version: 1.0
 **/
public class WeChatUtil {

    //公众号唯一标识
    public static final String APPID = "wx89628be75924923b";
    //公众号的appsecret
    public static final String APPSECRET = "bd9f308a62f8f419cdd6906b3b39294c";
    //获取网页授权accessToken的接口
    public static final String GET_WEB_ACCESSTOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";

    //获取用户信息的接口
    public static final String GET_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

    //网页授权的地址常量
    public static final String WEB_REDIRECT_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
            "appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo#wechat_redirect";

    /**
     * 获取网页授权的AccessToken凭据
     *
     * @return
     */
    public static JSONObject getWebAccessToken(String code) {
        JSONObject result = CommonUtil.httpsRequestToJsonObject(GET_WEB_ACCESSTOKEN_URL.replace("APPID", APPID).replace("SECRET", APPSECRET).replace("CODE", code), "GET", null);
        return result;
    }

    /**
     * 获取用户信息
     * accessToken  网页授权接口调用凭证,注意：此access_token与基础支持的access_token不同
     * return
     * {
     * "openid":" OPENID",
     * "nickname": "NICKNAME",
     * "sex":"1",
     * "province":"PROVINCE",
     * "city":"CITY",
     * "country":"COUNTRY",
     * "headimgurl": "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
     * "privilege":[ "PRIVILEGE1" "PRIVILEGE2"  ],
     * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
     * }
     */
    public static JSONObject getUserInfo(String accessToken, String openId) {
        JSONObject result = CommonUtil.httpsRequestToJsonObject(GET_USERINFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId), "GET", null);
        return result;
    }

    /**
     * 计算jssdk-config的签名
     *
     * @param noncestr
     * @param url
     * @return
     */
    public static String getSignature(String timestamp, String noncestr, String url) {
        //对所有待签名参数按照字段名的ASCII 码从小到大排序（字典序）
        Map< String, String > map = new TreeMap<>( );
        String ticket = getTicket( );
        map.put("jsapi_ticket", ticket);
        map.put("noncestr", noncestr);
        map.put("timestamp", timestamp);
        map.put("url", url);
        //使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串string1
        StringBuilder sb = new StringBuilder( );
        Set< String > set = map.keySet( );
        for (String key : set) {
            sb.append(key + "=" + map.get(key)).append("&");
        }
        //去掉最后一个&符号
        String temp = sb.substring(0, sb.length( ) - 1);
        //使用sha1加密
        String signature = DigestUtils.sha1Hex(temp);
        return signature;
    }

    /**
     * 获取 jsapiTick 票据 , 和accessToken
     * @return
     */
    public static String getTicket( ) {
        String accessToken = getAccessToken( );
        Map< String, Object > jsapi_ticket = (Map< String, Object >) CommonUtil.getCache("jsapi_ticket");
        if (jsapi_ticket == null || (System.currentTimeMillis( ) / 1000) - 5000 > (long) jsapi_ticket.get("long_time")) {
            JSONObject result = CommonUtil.httpsRequestToJsonObject("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi".replace("ACCESS_TOKEN", accessToken), "GET", null);
            HashMap< String, Object > map = new HashMap<>( );
            map.put("jsapi_ticket", result.get("ticket").toString( ));
            map.put("long_time", (System.currentTimeMillis( ) / 1000));
            CommonUtil.setCache("jsapi_ticket", map);
            return result.getString("ticket");
        }
        return (String) jsapi_ticket.get("jsapi_ticket");
    }

    /**
     * 获取基础的 accessToken
     * 参数： appid , secret
     * 注意： access_token的是有时间限制的：7200s , 　每日限额2000次
     *
     * @return
     */
    public static String getAccessToken( ) {
        //放到本地缓存里
        Map< String, Object > access_token = (Map< String, Object >) CommonUtil.getCache("access_token");
        if (access_token == null || (System.currentTimeMillis( ) / 1000) - 5000 > (long) access_token.get("long_time")) {
            JSONObject result = CommonUtil.httpsRequestToJsonObject("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET".replace("APPID", APPID).replace("APPSECRET", APPSECRET), "GET", null);
            HashMap< String, Object > map = new HashMap<>( );
            map.put("access_token", result.get("access_token").toString( ));
            map.put("long_time", (System.currentTimeMillis( ) / 1000));
            CommonUtil.setCache("access_token", map);
            return result.get("access_token").toString( );
        }
        return (String) access_token.get("access_token");
    }



}
