package com.cxyxiaomo.epp.access.service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.cxyxiaomo.epp.access.dao.SettingDao;
import com.cxyxiaomo.epp.access.pojo.UnlimitedQRCodeParam;
import com.cxyxiaomo.epp.access.utils.RestUtil;
import com.cxyxiaomo.epp.common.pojo.Setting;
import lombok.SneakyThrows;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
public class WeChatTokenServiceImpl implements WeChatTokenService {

    @Autowired
    SettingDao accessDao;

    // 数据库中该 key 保存的 time 是失效时间
    final String SETTING_KEY = "wechat_access_token";

    // 小程序信息
    // 小程序测试号
    // final String APPID = "wxa70348746d2b562f";
    // final String APPSECRET = "7da57703136fefb0584a5a6ab1aca152";
    // 小程序个人号
    final String APPID = "wx332e2e578f09873a";
    final String APPSECRET = "ebcd79d303e37983d691fe1dfdfb8818";

    @Override
    public String getAccessToken() {
        // 首先从数据库中查询是否存在 access_token
        // 如果存在且没有过期，那么就直接返回（距离失效时间小于 3 分钟就当作过期）
        Setting atSetting = accessDao.getValueByKey(SETTING_KEY);
        if (atSetting != null && LocalDateTime.now().plusMinutes(3L).compareTo(atSetting.getTime()) < 0) {
            return atSetting.getValue();
        }

        // 否则则去请求一个新的 access_token
        JSONObject jsonObject = getAccessTokenFromApi();
        String access_token = jsonObject.getString("access_token");
        Integer expires_in = jsonObject.getInteger("expires_in");

        // 如果请求成功，那么更新数据库中的记录
        if (access_token != null) {
            Setting setting = new Setting();
            setting.setKey(SETTING_KEY);
            setting.setValue(access_token);
            setting.setTime(LocalDateTime.now().plusSeconds(expires_in));
            accessDao.updateSetting(setting);
        }

        return access_token;

        // Map<String, Object> map = new HashMap<>();
        // map.put("raw", jsonObject);
        // if (access_token == null) {
        //     // 获取失败
        //     Integer errcode = jsonObject.getInteger("errcode");
        //     String errmsg = jsonObject.getString("errmsg");
        //     map.put("errcode", errcode);
        //     map.put("errmsg", errmsg);
        // } else {
        //     // 获取成功
        //     map.put("access_token", access_token);
        //     map.put("expires_in", expires_in);
        // }
        // return map;
    }

    private JSONObject getAccessTokenFromApi() {
        // refer: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html
        String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", APPID, APPSECRET);

        HttpHeaders headers = new HttpHeaders();
        // headers.set("Authorization", "Token " + this.accessToken);

        String jsonStr = RestUtil.doGetRequest(url, headers);
        return JSONObject.parseObject(jsonStr);
    }

    @SneakyThrows
    public ResponseBody getUnlimitedQRCodeFromApi(String accessToken, UnlimitedQRCodeParam unlimitedQRCodeParam) {
        // refer: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html
        String url = String.format("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s", accessToken);

        //添加参数
        Map<String, Object> params = new HashMap<>();
        params.put("scene", unlimitedQRCodeParam.getScene());
        params.put("page", unlimitedQRCodeParam.getPage());
        params.put("check_path", unlimitedQRCodeParam.getCheckPath());
        params.put("env_version", unlimitedQRCodeParam.getEnvVersion());
        params.put("width", unlimitedQRCodeParam.getWidth());
        params.put("auto_color",unlimitedQRCodeParam.getAutoColor());
        params.put("is_hyaline",unlimitedQRCodeParam.getIsHyaline());
        String paramsString = JSON.toJSONString(params);

        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .addHeader("content-type", "application/json")
                .url(url)
                .post(RequestBody.create(paramsString, MediaType.parse("application/json; charset=utf-8")))
                .build();
        Response response = okHttpClient.newCall(request).execute();
        // String result = response.body()response.body().string();

        // System.out.println("headers: " + response.headers());
        // System.out.println("body: " + response.body());
        System.out.println("paramsString: " + paramsString);
        return response.body();
    }
}
