package com.fs.wx.order.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.*;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fs.core.config.WxMaConfiguration;
import com.fs.wx.order.dto.UploadShippingInfoRequest;
import com.fs.wx.order.dto.WeChatApiConfig;
import com.fs.wx.order.dto.WeChatApiResponse;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;

@Slf4j
@Service
public class ShippingService {


    private final WeChatApiConfig weChatApiConfig;

    public ShippingService(WeChatApiConfig weChatApiConfig) {
        this.weChatApiConfig = weChatApiConfig;
    }

    /**
     * 调用微信 API 上传发货信息 (使用 Hutool HttpUtil)
     * @param request 发货信息请求体
     * @return 微信 API 的响应
     */
    public WeChatApiResponse uploadShippingInfo(UploadShippingInfoRequest request) throws WxErrorException {
        final WxMaService weChatAuthService = WxMaConfiguration.getMaService(request.getAppid());
        String accessToken = weChatAuthService.getAccessToken(false);
        if (accessToken == null) {
            log.error("获取微信 Access Token 失败");
            WeChatApiResponse errorResponse = new WeChatApiResponse();
            errorResponse.setErrcode(-3); // 自定义错误码，表示获取Token失败
            errorResponse.setErrmsg("获取微信 Access Token 失败");
            return errorResponse;
        }

        String url = UriComponentsBuilder.fromHttpUrl(weChatApiConfig.getUploadShippingInfoUrl())
                .queryParam("access_token", accessToken)
                .toUriString();

        log.debug("请求微信上传发货接口 Appid: {} URL: {}", request.getAppid(),url);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String requestBodyJson = null;
        try {
            requestBodyJson = objectMapper.writeValueAsString(request);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        log.debug("请求体 JSON: {}", requestBodyJson);


        HttpResponse httpResponse = null;
        try {
            HttpRequest httpRequest = HttpUtil.createPost(url)
                    .header(Header.CONTENT_TYPE, ContentType.JSON.getValue())
                    .body(requestBodyJson)
                    .timeout(10000);

            httpResponse = httpRequest.execute();

            int statusCode = httpResponse.getStatus();
            String responseBodyString = httpResponse.body();

            log.info("微信接口响应状态: {}", statusCode);
            log.info("微信接口响应体: {}", responseBodyString);

            if (httpResponse.isOk()) {
                WeChatApiResponse weChatApiResponse = JSONUtil.toBean(responseBodyString, WeChatApiResponse.class);

                if (!weChatApiResponse.isSuccess()) {
                    log.warn("微信接口返回业务错误: code={}, message={}", weChatApiResponse.getErrcode(), weChatApiResponse.getErrmsg());
                    if(ObjectUtil.equal(weChatApiResponse.getErrcode(),40001)) {
                        accessToken = weChatAuthService.getAccessToken(true);
                        log.info("token缓存失效，清除token，等待下次执行...");
                    }
                }
                return weChatApiResponse;

            } else {
                log.error("调用微信接口收到非成功状态码: {}", statusCode);
                try {
                    WeChatApiResponse errorResponse = JSONUtil.toBean(responseBodyString, WeChatApiResponse.class);
                    if (errorResponse.getErrcode() == null) {
                        errorResponse.setErrcode(statusCode);
                        errorResponse.setErrmsg("微信接口HTTP错误，状态码: " + statusCode + ", 响应体: " + responseBodyString);
                    }
                    return errorResponse;
                } catch (Exception parseEx) {
                    log.warn("无法将微信错误响应体解析为JSON: {}", responseBodyString, parseEx);
                    WeChatApiResponse errorResponse = new WeChatApiResponse();
                    errorResponse.setErrcode(statusCode);
                    errorResponse.setErrmsg("调用微信接口失败，状态码: " + statusCode + ", 原始响应体: " + responseBodyString);
                    return errorResponse;
                }
            }
        } catch (HttpException e) {
            log.error("调用微信接口发生HTTP异常: {}", e.getMessage(), e);
            WeChatApiResponse errorResponse = new WeChatApiResponse();
            errorResponse.setErrcode(-1);
            String detailedMessage = ExceptionUtil.getMessage(e);
            errorResponse.setErrmsg("调用微信接口时发生HTTP异常: " + detailedMessage);
            if (httpResponse != null) {
                errorResponse.setErrmsg(errorResponse.getErrmsg() + ", HTTP状态码: " + httpResponse.getStatus());
            }
            return errorResponse;
        } catch (Exception e) {
            log.error("调用微信接口时发生意外错误", e);
            WeChatApiResponse errorResponse = new WeChatApiResponse();
            errorResponse.setErrcode(-2);
            errorResponse.setErrmsg("调用微信接口时发生内部服务器错误: " + e.getMessage());
            return errorResponse;
        }finally {
            if(httpResponse != null) {
                httpResponse.close();
            }
        }
    }
}
