package com.kym.common.utils.wx;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.kym.common.utils.HttpUtil;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;

import java.io.IOException;
import java.util.Map;

/**
 * 微信小程序二维码工具类
 *
 * @author skyline
 * @since 2026-06-03
 */
public class WxMaQrCodeUtil {

    private static final Logger log = LoggerFactory.getLogger(WxMaQrCodeUtil.class);
    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder().build();
    private static String accessToken;
    private static long expiresAt;

    private WxMaQrCodeUtil() {
    }

    private static synchronized String getAccessToken() {
        if (accessToken != null && System.currentTimeMillis() < expiresAt) {
            return accessToken;
        }
        try {
            Environment env = SpringUtil.getBean(Environment.class);
            String appId = env.getProperty("wechat.miniapp.appid");
            String secret = env.getProperty("wechat.miniapp.secret");
            String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
                    appId, secret);
            String resp = HttpUtil.get(url);
            JSONObject json = JSON.parseObject(resp);
            accessToken = json.getString("access_token");
            int expiresIn = json.getIntValue("expires_in", 7200);
            expiresAt = System.currentTimeMillis() + (expiresIn - 300) * 1000L;
            log.info("获取小程序access_token成功");
            return accessToken;
        } catch (Exception e) {
            log.error("获取小程序access_token失败", e);
            throw new RuntimeException("获取小程序access_token失败", e);
        }
    }

    /**
     * 生成小程序码（无限数量），返回图片二进制数据
     *
     * @param scene 场景值（最大32字符）
     * @param page  小程序页面路径
     * @return 图片二进制数据
     */
    public static byte[] generateUnlimitedQrCode(String scene, String page) {
        try {
            String token = getAccessToken();
            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token;

            Map<String, Object> body = Map.of("scene", scene, "page", page, "check_path", false);
            String json = JSON.toJSONString(body);

            Request request = new Request.Builder()
                    .url(url)
                    .post(RequestBody.create(json, MediaType.get("application/json; charset=utf-8")))
                    .build();

            try (Response response = HTTP_CLIENT.newCall(request).execute()) {
                byte[] bytes = response.body().bytes();
                String contentType = response.header("Content-Type", "");
                // 如果返回的是JSON，说明出错了
                if (contentType.contains("application/json")) {
                    String resp = new String(bytes);
                    log.error("生成小程序码失败: {}", resp);
                    throw new RuntimeException("生成小程序码失败: " + resp);
                }
                return bytes;
            }
        } catch (IOException e) {
            log.error("生成小程序码异常", e);
            throw new RuntimeException("生成小程序码异常", e);
        }
    }

    /**
     * 清除缓存的access_token（用于强制刷新）
     */
    public static void clearTokenCache() {
        accessToken = null;
        expiresAt = 0;
    }
}
