package com.backendsys.modules.app.user.utils.AuthWechat;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;

@Component
public class WechatUtil {

    @Value("${wechat.miniprogram.appid}")
    private String APPID;
    @Value("${wechat.miniprogram.app-secret}")
    private String APP_SECRET;

    /**
     *
     * 微信 - 小程序登录
     * https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
     * - errcode: 错误码，请求失败时返回
     * [失败] 返回值：{"errcode":40164,"errmsg":"invalid ip 116.31.165.86 ipv6 ::ffff:116.31.165.86, not in whitelist, rid: 67d15951-5b3f2778-79d6f047"}
     * [成功] 返回值：{"session_key":"uQAcry2PC1Lx/Krp+6rr0g==","openid":"oSB9r7T7kN1bC7PabJ7RmTUiaJmo"}
     */
    public JSONObject getCode2Session(String code) {
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String, Object> params = new LinkedHashMap<>();
        params.put("appid", APPID);
        params.put("secret", APP_SECRET);
        params.put("js_code", code);
        params.put("grant_type", "authorization_code");
        String result = HttpUtil.post(url, params);
        return JSONUtil.parseObj(result);
    }

    /**
     * 获取接口调用凭据
     * https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
     * https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html
     * 返回值：{ access_token, expires_in }
     */
    public JSONObject getStableAccessToken() {
        String url = "https://api.weixin.qq.com/cgi-bin/stable_token";
        Map<String, Object> params = new LinkedHashMap<>();
        params.put("appid", APPID);
        params.put("secret", APP_SECRET);
        params.put("grant_type", "client_credential");
        // - force_refresh: 默认使用 false。
        // 1. force_refresh = false 时为普通调用模式，access_token 有效期内重复调用该接口不会更新 access_token；
        // 2. 当force_refresh = true 时为强制刷新模式，会导致上次获取的 access_token 失效，并返回新的 access_token
        String result = HttpUtil.post(url, params);

        // 再写个缓存，这里是开发者调用接口时的凭证

        return JSONUtil.parseObj(result);
    }

}
