package shop.alien.gateway.thirdparty;

import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import shop.alien.gateway.config.LifeUserThirdBindProperties;

import java.time.Duration;

/**
 * 微信开放平台「移动应用」OAuth2：App 内 SDK 授权 code 换 openid/unionid。
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class WeChatMobileOAuthClient {

    private static final String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";

    private final LifeUserThirdBindProperties properties;

    @Value("${wechat.open.mobileAppId:}")
    private String wechatMobileAppIdFallback;

    @Value("${wechat.open.mobileAppSecret:}")
    private String wechatMobileAppSecretFallback;

    private final WebClient webClient = WebClient.builder().build();

    public OAuthExchangeResult exchangeCode(String code) {
        OAuthExchangeResult result = new OAuthExchangeResult();
        String appId = StringUtils.firstNonBlank(
                properties.getWechat().getMobileAppId(),
                wechatMobileAppIdFallback);
        String secret = StringUtils.firstNonBlank(
                properties.getWechat().getMobileAppSecret(),
                wechatMobileAppSecretFallback);
        if (StringUtils.isBlank(appId) || StringUtils.isBlank(secret)) {
            result.setErrmsg("未配置微信移动应用 appId/appSecret（life.user.third-bind.wechat.mobile-app-id 或 wechat.open.mobileAppId）");
            return result;
        }
        if (StringUtils.isBlank(code)) {
            result.setErrmsg("code 不能为空");
            return result;
        }
        String url = UriComponentsBuilder.fromHttpUrl(OAUTH2_ACCESS_TOKEN_URL)
                .queryParam("appid", appId)
                .queryParam("secret", secret)
                .queryParam("code", code)
                .queryParam("grant_type", "authorization_code")
                .build(true)
                .toUriString();
        try {
            String body = webClient.get()
                    .uri(url)
                    .retrieve()
                    .bodyToMono(String.class)
                    .block(Duration.ofSeconds(15));
            log.info("微信 App oauth2/access_token 已返回, bodyLength={}", body != null ? body.length() : 0);
            if (StringUtils.isBlank(body)) {
                result.setErrmsg("微信接口无响应");
                return result;
            }
            JSONObject json = JSONObject.parseObject(body);
            if (json.containsKey("errcode") && json.getIntValue("errcode") != 0) {
                result.setErrcode(json.getInteger("errcode"));
                result.setErrmsg(json.getString("errmsg"));
                return result;
            }
            result.setOpenid(json.getString("openid"));
            result.setUnionid(json.getString("unionid"));
            if (StringUtils.isBlank(result.getOpenid())) {
                result.setErrmsg("未返回 openid");
            }
            return result;
        } catch (Exception e) {
            log.error("调用微信 App oauth2/access_token 异常", e);
            result.setErrmsg("调用微信接口失败");
            return result;
        }
    }

    @Data
    public static class OAuthExchangeResult {
        private String openid;
        private String unionid;
        private Integer errcode;
        private String errmsg;

        public boolean isSuccess() {
            return errcode == null && StringUtils.isNotBlank(openid);
        }
    }
}
