package org.jeecg.modules.app.weixinService;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.jeecg.config.vo.weixin.WechatMiniProgramProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class WechatAccessTokenService {

    private static final Logger logger = LoggerFactory.getLogger(WechatAccessTokenService.class);

    private final WechatMiniProgramProperties properties;
    private final CloseableHttpClient httpClient;

    private String accessToken;
    private long expireTime;
    private final Object lock = new Object();

    public WechatAccessTokenService(WechatMiniProgramProperties properties,
                                    CloseableHttpClient httpClient) {
        this.properties = properties;
        this.httpClient = httpClient;
    }

    public String getAccessToken() {
        if (!properties.isTokenCacheEnabled() || accessToken == null || System.currentTimeMillis() > expireTime) {
            synchronized (lock) {
                if (!properties.isTokenCacheEnabled() || accessToken == null || System.currentTimeMillis() > expireTime) {
                    refreshAccessToken();
                }
            }
        }
        return accessToken;
    }

    private void refreshAccessToken() {
        String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
                properties.getAppId(), properties.getAppSecret());

        try {
            HttpGet httpGet = new HttpGet(url);
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                String result = EntityUtils.toString(entity);
                JSONObject json = JSONObject.parseObject(result);

                if (json.containsKey("access_token")) {
                    accessToken = json.getString("access_token");
                    expireTime = System.currentTimeMillis() + (properties.getTokenCacheTimeout() * 1000);
                    logger.info("成功刷新微信AccessToken，有效期至: {}", new Date(expireTime));
                } else {
                    logger.error("获取微信AccessToken失败: {}", result);
                    throw new RuntimeException("获取微信AccessToken失败: " + json.getString("errmsg"));
                }
            }
        } catch (Exception e) {
            logger.error("刷新微信AccessToken异常", e);
            throw new RuntimeException("刷新微信AccessToken异常", e);
        }
    }
}
