package com.haha.service.payment.payscore.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.haha.common.constant.PaymentConstants;
import com.haha.common.enums.PayScoreState;
import com.haha.common.enums.PaymentChannel;
import com.haha.service.payment.config.WxPayConfig;
import com.haha.service.payment.payscore.*;
import com.wechat.pay.java.core.exception.HttpException;
import com.wechat.pay.java.core.exception.MalformedMessageException;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.http.HttpClient;
import com.wechat.pay.java.core.http.HttpMethod;
import com.wechat.pay.java.core.http.HttpRequest;
import com.wechat.pay.java.core.http.HttpResponse;
import com.wechat.pay.java.core.http.JsonRequestBody;
import com.wechat.pay.java.core.http.MediaType;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付分策略实现
 * 使用微信支付 V3 SDK core 模块的 HttpClient 发送自定义请求
 */
@Slf4j
@Component
public class WxPayScoreStrategy implements PayScoreStrategy {

    private static final String PAY_SCORE_BASE_URL = "https://api.mch.weixin.qq.com/v3/payscore/serviceorder";

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired(required = false)
    private HttpClient wxPayHttpClient;

    @Autowired(required = false)
    private NotificationParser wxNotificationParser;

    @Autowired(required = false)
    private WxPayConfig wxPayConfig;

    @Override
    public PaymentChannel getChannel() {
        return PaymentChannel.WECHAT;
    }

    @Override
    public PayScoreResult createServiceOrder(PayScoreCreateRequest request) {
        log.info("[微信支付分] 创建服务订单 - 订单号: {}, 设备: {}", request.getOutOrderNo(), request.getStartDeviceId());

        // 空检查
        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        try {
            // 构建请求体 JSON
            ObjectNode body = objectMapper.createObjectNode();
            body.put("out_order_no", request.getOutOrderNo());
            body.put("appid", wxPayConfig.getAppId());
            body.put("service_id", wxPayConfig.getServiceId());
            body.put("service_introduction", request.getServiceIntroduction());
            body.put("notify_url", wxPayConfig.getPayScoreNotifyUrl());
            body.put("need_user_confirm", true);

            // 后付费项目
            if (request.getPostPayments() != null && !request.getPostPayments().isEmpty()) {
                ArrayNode postPayments = objectMapper.createArrayNode();
                for (PayScoreCreateRequest.PostPayment payment : request.getPostPayments()) {
                    ObjectNode paymentObj = objectMapper.createObjectNode();
                    paymentObj.put("name", payment.getName());
                    paymentObj.put("amount", yuanToFen(payment.getAmount()));
                    if (payment.getDescription() != null) {
                        paymentObj.put("description", payment.getDescription());
                    }
                    if (payment.getCount() != null) {
                        paymentObj.put("count", payment.getCount());
                    }
                    postPayments.add(paymentObj);
                }
                body.set("post_payments", postPayments);
            }

            // 风险金
            ObjectNode riskFund = objectMapper.createObjectNode();
            riskFund.put("name", request.getRiskFundName() != null ? request.getRiskFundName() : "DEPOSIT");
            riskFund.put("amount", yuanToFen(request.getRiskFundAmount()));
            body.set("risk_fund", riskFund);

            // 服务时间段
            ObjectNode timeRange = objectMapper.createObjectNode();
            timeRange.put("start_time", request.getStartTime() != null ? request.getStartTime() : "OnAccept");
            if (request.getEndTime() != null) {
                timeRange.put("end_time", request.getEndTime());
            }
            body.set("time_range", timeRange);

            // 服务位置（设备）
            if (request.getStartDeviceId() != null) {
                ObjectNode location = objectMapper.createObjectNode();
                location.put("start_location", request.getStartDeviceId());
                if (request.getEndDeviceId() != null) {
                    location.put("end_location", request.getEndDeviceId());
                }
                body.set("location", location);
            }

            // 附加数据
            if (request.getAttach() != null) {
                body.put("attach", request.getAttach());
            }

            // 用户标识（如果需要免确认，可传入 openid）
            if (request.getOpenId() != null) {
                body.put("openid", request.getOpenId());
            }

            String requestBody = objectMapper.writeValueAsString(body);
            log.info("[微信支付分] 创建订单请求体: {}", requestBody);

            // 发送 POST 请求
            HttpRequest httpRequest = new HttpRequest.Builder()
                    .httpMethod(HttpMethod.POST)
                    .url(PAY_SCORE_BASE_URL)
                    .body(new JsonRequestBody.Builder().body(requestBody).build())
                    .addHeader("Content-Type", MediaType.APPLICATION_JSON.getValue())
                    .addHeader("Accept", MediaType.APPLICATION_JSON.getValue())
                    .build();

            HttpResponse<Map> response = wxPayHttpClient.execute(httpRequest, Map.class);

            // 解析响应
            Map<String, Object> responseMap = response.getServiceResponse();
            JsonNode respJson = objectMapper.valueToTree(responseMap);


            String outOrderNo = getJsonString(respJson, "out_order_no");
            String state = getJsonString(respJson, "state");
            String packageStr = getJsonString(respJson, "package");

            PayScoreResult result = PayScoreResult.success(outOrderNo, state);
            result.setPackageStr(packageStr);

            Map<String, Object> rawData = new HashMap<>();
            rawData.put("response", responseMap);
            result.setRawData(rawData);

            log.info("[微信支付分] 创建订单成功 - 订单号: {}, 状态: {}, package: {}", outOrderNo, state, packageStr);
            return result;

        } catch (HttpException e) {
            log.error("[微信支付分] 创建订单HTTP异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("NETWORK_ERROR", "网络请求异常: " + e.getMessage());
        } catch (ServiceException e) {
            log.error("[微信支付分] 创建订单业务异常: code={}, msg={}", e.getErrorCode(), e.getErrorMessage(), e);
            return PayScoreResult.fail(e.getErrorCode(), e.getErrorMessage());
        } catch (MalformedMessageException e) {
            log.error("[微信支付分] 创建订单消息解析异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("MESSAGE_ERROR", "消息解析异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("[微信支付分] 创建订单未知异常", e);
            return PayScoreResult.fail("UNKNOWN_ERROR", "创建订单失败: " + e.getMessage());
        }
    }

    @Override
    public PayScoreResult completeServiceOrder(PayScoreCompleteRequest request) {
        log.info("[微信支付分] 完结服务订单 - 订单号: {}, 总金额: {}元", request.getOutOrderNo(), request.getTotalAmount());

        // 空检查
        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        try {
            // 构建请求体 JSON
            ObjectNode body = objectMapper.createObjectNode();
            body.put("appid", wxPayConfig.getAppId());
            body.put("service_id", wxPayConfig.getServiceId());

            // 后付费项目（实际收费）- 必填，无人设备行业必须回传交易内容
            ArrayNode postPayments = objectMapper.createArrayNode();
            if (request.getPostPayments() != null && !request.getPostPayments().isEmpty()) {
                for (PayScoreCreateRequest.PostPayment payment : request.getPostPayments()) {
                    ObjectNode paymentObj = objectMapper.createObjectNode();
                    paymentObj.put("name", payment.getName());
                    paymentObj.put("amount", yuanToFen(payment.getAmount()));
                    if (payment.getDescription() != null) {
                        paymentObj.put("description", payment.getDescription());
                    }
                    if (payment.getCount() != null) {
                        paymentObj.put("count", payment.getCount());
                    }
                    postPayments.add(paymentObj);
                }
            } else {
                log.warn("[微信支付分] 完结订单未提供post_payments，使用fallback - orderNo: {}", request.getOutOrderNo());
                ObjectNode paymentObj = objectMapper.createObjectNode();
                paymentObj.put("name", "商品信息");
                paymentObj.put("amount", yuanToFen(request.getTotalAmount()));
                paymentObj.put("description", "商品");
                paymentObj.put("count", 1);
                postPayments.add(paymentObj);
            }
            body.set("post_payments", postPayments);

            // 商户优惠
            if (request.getPostDiscounts() != null && !request.getPostDiscounts().isEmpty()) {
                ArrayNode postDiscounts = objectMapper.createArrayNode();
                for (PayScoreCompleteRequest.PostDiscount discount : request.getPostDiscounts()) {
                    ObjectNode discountObj = objectMapper.createObjectNode();
                    discountObj.put("name", discount.getName());
                    if (discount.getDescription() != null) {
                        discountObj.put("description", discount.getDescription());
                    }
                    if (discount.getAmount() != null) {
                        discountObj.put("amount", yuanToFen(discount.getAmount()));
                    }
                    if (discount.getCount() != null) {
                        discountObj.put("count", discount.getCount());
                    }
                    postDiscounts.add(discountObj);
                }
                body.set("post_discounts", postDiscounts);
            }

            // 总金额
            body.put("total_amount", yuanToFen(request.getTotalAmount()));

            // 服务时间段
            if (request.getEndTime() != null) {
                ObjectNode timeRange = objectMapper.createObjectNode();
                timeRange.put("end_time", request.getEndTime());
                body.set("time_range", timeRange);
            }

            // 服务位置（设备）
            if (request.getStartDeviceId() != null || request.getEndDeviceId() != null) {
                ObjectNode location = objectMapper.createObjectNode();
                if (request.getStartDeviceId() != null) {
                    location.put("start_location", request.getStartDeviceId());
                }
                if (request.getEndDeviceId() != null) {
                    location.put("end_location", request.getEndDeviceId());
                }
                body.set("location", location);
            }

            String requestBody = objectMapper.writeValueAsString(body);
            String url = PAY_SCORE_BASE_URL + "/" + request.getOutOrderNo() + "/complete";
            log.info("[微信支付分] 完结订单请求: url={}, body={}", url, requestBody);

            // 发送 POST 请求
            HttpRequest httpRequest = new HttpRequest.Builder()
                    .httpMethod(HttpMethod.POST)
                    .url(url)
                    .body(new JsonRequestBody.Builder().body(requestBody).build())
                    .addHeader("Content-Type", MediaType.APPLICATION_JSON.getValue())
                    .addHeader("Accept", MediaType.APPLICATION_JSON.getValue())
                    .build();

            HttpResponse<Map> response = wxPayHttpClient.execute(httpRequest, Map.class);

            // 解析响应体
            Map<String, Object> responseMap = response.getServiceResponse();
            JsonNode respJson = objectMapper.valueToTree(responseMap);

            if (responseMap != null && !responseMap.isEmpty()) {
                String outOrderNo = getJsonString(respJson, "out_order_no");
                String state = getJsonString(respJson, "state");
                log.info("[微信支付分] 完结订单成功 - 订单号: {}, 状态: {}", outOrderNo, state);
                return PayScoreResult.success(outOrderNo != null ? outOrderNo : request.getOutOrderNo(),
                        state != null ? state : PayScoreState.USER_PAYING.getCode());
            }

            log.info("[微信支付分] 完结订单成功 - 订单号: {}", request.getOutOrderNo());
            return PayScoreResult.success(request.getOutOrderNo(), PayScoreState.USER_PAYING.getCode());

        } catch (HttpException e) {
            log.error("[微信支付分] 完结订单HTTP异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("NETWORK_ERROR", "网络请求异常: " + e.getMessage());
        } catch (ServiceException e) {
            log.error("[微信支付分] 完结订单业务异常: code={}, msg={}", e.getErrorCode(), e.getErrorMessage(), e);
            return PayScoreResult.fail(e.getErrorCode(), e.getErrorMessage());
        } catch (MalformedMessageException e) {
            log.error("[微信支付分] 完结订单消息解析异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("MESSAGE_ERROR", "消息解析异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("[微信支付分] 完结订单未知异常", e);
            return PayScoreResult.fail("UNKNOWN_ERROR", "完结订单失败: " + e.getMessage());
        }
    }

    @Override
    public PayScoreResult cancelServiceOrder(PayScoreCancelRequest request) {
        log.info("[微信支付分] 取消服务订单 - 订单号: {}, 原因: {}", request.getOutOrderNo(), request.getReason());

        // 空检查
        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        try {
            // 构建请求体 JSON
            ObjectNode body = objectMapper.createObjectNode();
            body.put("appid", wxPayConfig.getAppId());
            body.put("service_id", wxPayConfig.getServiceId());
            body.put("reason", request.getReason() != null ? request.getReason() : "用户取消");

            String requestBody = objectMapper.writeValueAsString(body);
            String url = PAY_SCORE_BASE_URL + "/" + request.getOutOrderNo() + "/cancel";
            log.info("[微信支付分] 取消订单请求: url={}, body={}", url, requestBody);

            // 发送 POST 请求
            HttpRequest httpRequest = new HttpRequest.Builder()
                    .httpMethod(HttpMethod.POST)
                    .url(url)
                    .body(new JsonRequestBody.Builder().body(requestBody).build())
                    .addHeader("Content-Type", MediaType.APPLICATION_JSON.getValue())
                    .addHeader("Accept", MediaType.APPLICATION_JSON.getValue())
                    .build();

            HttpResponse<Map> response = wxPayHttpClient.execute(httpRequest, Map.class);

            // 解析响应体
            Map<String, Object> responseMap = response.getServiceResponse();
            JsonNode respJson = objectMapper.valueToTree(responseMap);

            if (responseMap != null && !responseMap.isEmpty()) {
                String outOrderNo = getJsonString(respJson, "out_order_no");
                String state = getJsonString(respJson, "state");
                log.info("[微信支付分] 取消订单成功 - 订单号: {}, 状态: {}", outOrderNo, state);
                return PayScoreResult.success(outOrderNo != null ? outOrderNo : request.getOutOrderNo(),
                        state != null ? state : PayScoreState.REVOKED.getCode());
            }

            log.info("[微信支付分] 取消订单成功 - 订单号: {}", request.getOutOrderNo());
            return PayScoreResult.success(request.getOutOrderNo(), PayScoreState.REVOKED.getCode());

        } catch (HttpException e) {
            log.error("[微信支付分] 取消订单HTTP异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("NETWORK_ERROR", "网络请求异常: " + e.getMessage());
        } catch (ServiceException e) {
            log.error("[微信支付分] 取消订单业务异常: code={}, msg={}", e.getErrorCode(), e.getErrorMessage(), e);
            return PayScoreResult.fail(e.getErrorCode(), e.getErrorMessage());
        } catch (MalformedMessageException e) {
            log.error("[微信支付分] 取消订单消息解析异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("MESSAGE_ERROR", "消息解析异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("[微信支付分] 取消订单未知异常", e);
            return PayScoreResult.fail("UNKNOWN_ERROR", "取消订单失败: " + e.getMessage());
        }
    }

    @Override
    public PayScoreResult queryServiceOrder(String outOrderNo) {
        log.info("[微信支付分] 查询服务订单 - 订单号: {}", outOrderNo);

        // 空检查
        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        try {
            // 构建查询 URL
            String url = PAY_SCORE_BASE_URL 
                    + "?out_order_no=" + outOrderNo 
                    + "&service_id=" + wxPayConfig.getServiceId() 
                    + "&appid=" + wxPayConfig.getAppId();
            log.info("[微信支付分] 查询订单请求: url={}", url);

            // 发送 GET 请求
            HttpRequest httpRequest = new HttpRequest.Builder()
                    .httpMethod(HttpMethod.GET)
                    .url(url)
                    .addHeader("Accept", MediaType.APPLICATION_JSON.getValue())
                    .build();

            HttpResponse<Map> response = wxPayHttpClient.execute(httpRequest, Map.class);

            // 解析响应
            Map<String, Object> responseMap = response.getServiceResponse();
            JsonNode respJson = objectMapper.valueToTree(responseMap);


            String respOutOrderNo = getJsonString(respJson, "out_order_no");
            String state = getJsonString(respJson, "state");

            PayScoreResult result = PayScoreResult.success(respOutOrderNo, state);

            // 解析总金额
            if (respJson.has("total_amount") && !respJson.get("total_amount").isNull()) {
                int totalAmountFen = respJson.get("total_amount").asInt();
                result.setTotalAmount(fenToYuan(totalAmountFen));
            }

            // 提取微信支付订单号
            if (respJson.has("collection")) {
                JsonNode collection = respJson.get("collection");
                if (collection.has("details") && collection.get("details").isArray()) {
                    JsonNode details = collection.get("details");
                    if (details.size() > 0) {
                        String transactionId = getJsonString(details.get(0), "transaction_id");
                        result.setTransactionId(transactionId);
                    }
                }
            }

            Map<String, Object> rawData = new HashMap<>();
            rawData.put("response", responseMap);
            result.setRawData(rawData);

            log.info("[微信支付分] 查询订单成功 - 订单号: {}, 状态: {}, 金额: {}元, transactionId: {}",
                    respOutOrderNo, state, result.getTotalAmount(), result.getTransactionId());
            return result;

        } catch (HttpException e) {
            log.error("[微信支付分] 查询订单HTTP异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("NETWORK_ERROR", "网络请求异常: " + e.getMessage());
        } catch (ServiceException e) {
            log.error("[微信支付分] 查询订单业务异常: code={}, msg={}", e.getErrorCode(), e.getErrorMessage(), e);
            return PayScoreResult.fail(e.getErrorCode(), e.getErrorMessage());
        } catch (MalformedMessageException e) {
            log.error("[微信支付分] 查询订单消息解析异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("MESSAGE_ERROR", "消息解析异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("[微信支付分] 查询订单未知异常", e);
            return PayScoreResult.fail("UNKNOWN_ERROR", "查询订单失败: " + e.getMessage());
        }
    }

    @Override
    public PayScoreResult modifyServiceOrder(PayScoreModifyRequest request) {
        log.info("[微信支付分] 修改订单金额 - 订单号: {}, 新金额: {}元", request.getOutOrderNo(), request.getTotalAmount());

        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        try {
            ObjectNode body = objectMapper.createObjectNode();
            body.put("appid", wxPayConfig.getAppId());
            body.put("service_id", wxPayConfig.getServiceId());

            // 后付费项目 - 必填，无人设备行业必须回传交易内容
            ArrayNode postPayments = objectMapper.createArrayNode();
            if (request.getPostPayments() != null && !request.getPostPayments().isEmpty()) {
                for (PayScoreModifyRequest.PostPayment payment : request.getPostPayments()) {
                    ObjectNode paymentObj = objectMapper.createObjectNode();
                    paymentObj.put("name", payment.getName());
                    paymentObj.put("amount", yuanToFen(payment.getAmount()));
                    if (payment.getDescription() != null) {
                        paymentObj.put("description", payment.getDescription());
                    }
                    if (payment.getCount() != null) {
                        paymentObj.put("count", payment.getCount());
                    }
                    postPayments.add(paymentObj);
                }
            } else {
                log.warn("[微信支付分] 修改订单未提供post_payments，使用fallback - orderNo: {}", request.getOutOrderNo());
                ObjectNode paymentObj = objectMapper.createObjectNode();
                paymentObj.put("name", "商品信息");
                paymentObj.put("amount", yuanToFen(request.getTotalAmount()));
                paymentObj.put("description", "商品");
                paymentObj.put("count", 1);
                postPayments.add(paymentObj);
            }
            body.set("post_payments", postPayments);

            body.put("total_amount", yuanToFen(request.getTotalAmount()));
            body.put("reason", request.getReason() != null ? request.getReason() : "金额调整");

            String requestBody = objectMapper.writeValueAsString(body);
            String url = PAY_SCORE_BASE_URL + "/" + request.getOutOrderNo() + "/modify";
            log.info("[微信支付分] 修改金额请求: url={}, body={}", url, requestBody);

            HttpRequest httpRequest = new HttpRequest.Builder()
                    .httpMethod(HttpMethod.POST)
                    .url(url)
                    .body(new JsonRequestBody.Builder().body(requestBody).build())
                    .addHeader("Content-Type", MediaType.APPLICATION_JSON.getValue())
                    .addHeader("Accept", MediaType.APPLICATION_JSON.getValue())
                    .build();

            HttpResponse<Map> response = wxPayHttpClient.execute(httpRequest, Map.class);
            Map<String, Object> responseMap = response.getServiceResponse();
            JsonNode respJson = objectMapper.valueToTree(responseMap);

            String outOrderNo = getJsonString(respJson, "out_order_no");
            String state = getJsonString(respJson, "state");

            return PayScoreResult.success(outOrderNo, state);

        } catch (HttpException e) {
            log.error("[微信支付分] 修改金额HTTP异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("NETWORK_ERROR", "网络请求异常: " + e.getMessage());
        } catch (ServiceException e) {
            log.error("[微信支付分] 修改金额业务异常: code={}, msg={}", e.getErrorCode(), e.getErrorMessage(), e);
            return PayScoreResult.fail(e.getErrorCode(), e.getErrorMessage());
        } catch (MalformedMessageException e) {
            log.error("[微信支付分] 修改金额消息解析异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("MESSAGE_ERROR", "消息解析异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("[微信支付分] 修改金额未知异常", e);
            return PayScoreResult.fail("UNKNOWN_ERROR", "修改金额失败: " + e.getMessage());
        }
    }

    @Override
    public PayScoreResult syncServiceOrder(PayScoreSyncRequest request) {
        log.info("[微信支付分] 同步订单信息 - 订单号: {}, 类型: {}", request.getOutOrderNo(), request.getType());

        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        try {
            ObjectNode body = objectMapper.createObjectNode();
            body.put("appid", wxPayConfig.getAppId());
            body.put("service_id", wxPayConfig.getServiceId());
            body.put("type", request.getType() != null ? request.getType() : "ORDER_PAID");
            if (request.getDetail() != null) {
                body.put("detail", request.getDetail());
            }

            String requestBody = objectMapper.writeValueAsString(body);
            String url = PAY_SCORE_BASE_URL + "/" + request.getOutOrderNo() + "/sync";
            log.info("[微信支付分] 同步订单请求: url={}, body={}", url, requestBody);

            HttpRequest httpRequest = new HttpRequest.Builder()
                    .httpMethod(HttpMethod.POST)
                    .url(url)
                    .body(new JsonRequestBody.Builder().body(requestBody).build())
                    .addHeader("Content-Type", MediaType.APPLICATION_JSON.getValue())
                    .addHeader("Accept", MediaType.APPLICATION_JSON.getValue())
                    .build();

            HttpResponse<Map> response = wxPayHttpClient.execute(httpRequest, Map.class);
            Map<String, Object> responseMap = response.getServiceResponse();
            JsonNode respJson = objectMapper.valueToTree(responseMap);

            String outOrderNo = getJsonString(respJson, "out_order_no");
            String state = getJsonString(respJson, "state");

            return PayScoreResult.success(outOrderNo, state);

        } catch (HttpException e) {
            log.error("[微信支付分] 同步订单HTTP异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("NETWORK_ERROR", "网络请求异常: " + e.getMessage());
        } catch (ServiceException e) {
            log.error("[微信支付分] 同步订单业务异常: code={}, msg={}", e.getErrorCode(), e.getErrorMessage(), e);
            return PayScoreResult.fail(e.getErrorCode(), e.getErrorMessage());
        } catch (MalformedMessageException e) {
            log.error("[微信支付分] 同步订单消息解析异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("MESSAGE_ERROR", "消息解析异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("[微信支付分] 同步订单未知异常", e);
            return PayScoreResult.fail("UNKNOWN_ERROR", "同步订单失败: " + e.getMessage());
        }
    }

    @Override
    public PayScoreResult payServiceOrder(String outOrderNo) {
        log.info("[微信支付分] 发起支付扣款 - 订单号: {}", outOrderNo);

        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        try {
            ObjectNode body = objectMapper.createObjectNode();
            body.put("appid", wxPayConfig.getAppId());
            body.put("service_id", wxPayConfig.getServiceId());

            String requestBody = objectMapper.writeValueAsString(body);
            String url = PAY_SCORE_BASE_URL + "/" + outOrderNo + "/pay";
            log.info("[微信支付分] 支付请求: url={}, body={}", url, requestBody);

            HttpRequest httpRequest = new HttpRequest.Builder()
                    .httpMethod(HttpMethod.POST)
                    .url(url)
                    .body(new JsonRequestBody.Builder().body(requestBody).build())
                    .addHeader("Content-Type", MediaType.APPLICATION_JSON.getValue())
                    .addHeader("Accept", MediaType.APPLICATION_JSON.getValue())
                    .build();

            HttpResponse<Map> response = wxPayHttpClient.execute(httpRequest, Map.class);
            Map<String, Object> responseMap = response.getServiceResponse();
            JsonNode respJson = objectMapper.valueToTree(responseMap);

            String respOrderNo = getJsonString(respJson, "out_order_no");
            log.info("[微信支付分] 支付扣款成功 - 订单号: {}", respOrderNo);

            return PayScoreResult.success(respOrderNo, null);

        } catch (ServiceException e) {
            log.error("[微信支付分] 支付扣款业务异常: code={}, msg={}", e.getErrorCode(), e.getErrorMessage(), e);
            return PayScoreResult.fail(e.getErrorCode(), e.getErrorMessage());
        } catch (Exception e) {
            log.error("[微信支付分] 支付扣款异常", e);
            return PayScoreResult.fail("UNKNOWN_ERROR", "支付扣款失败: " + e.getMessage());
        }
    }

    @Override
    public PayScoreResult refundServiceOrder(PayScoreRefundRequest request) {
        log.info("[微信支付分] 申请退款 - 订单号: {}, 金额: {}元, transactionId: {}",
                request.getOutOrderNo(), request.getRefundAmount(), request.getTransactionId());

        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        if (request.getTransactionId() == null || request.getTransactionId().isEmpty()) {
            log.error("[微信支付分] 退款失败: transaction_id 为空，可能回调尚未处理完成");
            return PayScoreResult.fail("MISSING_TRANSACTION_ID", "缺少微信支付订单号，请等待支付回调完成后重试");
        }

        try {
            // 支付分退款使用通用退款接口 /v3/refund/domestic/refunds
            ObjectNode body = objectMapper.createObjectNode();
            body.put("transaction_id", request.getTransactionId());
            body.put("out_refund_no", request.getOutRefundNo() != null
                    ? request.getOutRefundNo() : "RF" + request.getOutOrderNo());
            body.put("reason", request.getReason() != null ? request.getReason() : "用户申请退款");

            ObjectNode amount = objectMapper.createObjectNode();
            amount.put("refund", yuanToFen(request.getRefundAmount()));
            amount.put("total", request.getTotalAmount() != null
                    ? yuanToFen(request.getTotalAmount()) : yuanToFen(request.getRefundAmount()));
            amount.put("currency", "CNY");
            body.set("amount", amount);

            String requestBody = objectMapper.writeValueAsString(body);
            String url = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
            log.info("[微信支付分] 退款请求: url={}, body={}", url, requestBody);

            HttpRequest httpRequest = new HttpRequest.Builder()
                    .httpMethod(HttpMethod.POST)
                    .url(url)
                    .body(new JsonRequestBody.Builder().body(requestBody).build())
                    .addHeader("Content-Type", MediaType.APPLICATION_JSON.getValue())
                    .addHeader("Accept", MediaType.APPLICATION_JSON.getValue())
                    .build();

            HttpResponse<Map> response = wxPayHttpClient.execute(httpRequest, Map.class);
            Map<String, Object> responseMap = response.getServiceResponse();
            JsonNode respJson = objectMapper.valueToTree(responseMap);

            String refundId = getJsonString(respJson, "refund_id");
            String status = getJsonString(respJson, "status");

            PayScoreResult result = PayScoreResult.success(request.getOutOrderNo(), status);
            result.setPackageStr(refundId);
            log.info("[微信支付分] 退款申请成功 - refundId: {}, status: {}", refundId, status);
            return result;

        } catch (HttpException e) {
            log.error("[微信支付分] 退款HTTP异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("NETWORK_ERROR", "网络请求异常: " + e.getMessage());
        } catch (ServiceException e) {
            log.error("[微信支付分] 退款业务异常: code={}, msg={}", e.getErrorCode(), e.getErrorMessage(), e);
            return PayScoreResult.fail(e.getErrorCode(), e.getErrorMessage());
        } catch (MalformedMessageException e) {
            log.error("[微信支付分] 退款消息解析异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("MESSAGE_ERROR", "消息解析异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("[微信支付分] 退款未知异常", e);
            return PayScoreResult.fail("UNKNOWN_ERROR", "退款失败: " + e.getMessage());
        }
    }

    @Override
    public PayScoreResult queryRefund(String outOrderNo, String outRefundNo) {
        log.info("[微信支付分] 查询退款 - 订单号: {}, 退款单号: {}", outOrderNo, outRefundNo);

        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        try {
            String url = PAY_SCORE_BASE_URL + "/" + outOrderNo + "/refund/" + outRefundNo
                    + "?service_id=" + wxPayConfig.getServiceId()
                    + "&appid=" + wxPayConfig.getAppId();
            log.info("[微信支付分] 查询退款请求: url={}", url);

            HttpRequest httpRequest = new HttpRequest.Builder()
                    .httpMethod(HttpMethod.GET)
                    .url(url)
                    .addHeader("Accept", MediaType.APPLICATION_JSON.getValue())
                    .build();

            HttpResponse<Map> response = wxPayHttpClient.execute(httpRequest, Map.class);
            Map<String, Object> responseMap = response.getServiceResponse();
            JsonNode respJson = objectMapper.valueToTree(responseMap);

            String status = getJsonString(respJson, "status");

            PayScoreResult result = PayScoreResult.success(outOrderNo, status);

            if (respJson.has("amount") && !respJson.get("amount").isNull()) {
                result.setTotalAmount(fenToYuan(respJson.get("amount").asInt()));
            }

            return result;

        } catch (HttpException e) {
            log.error("[微信支付分] 查询退款HTTP异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("NETWORK_ERROR", "网络请求异常: " + e.getMessage());
        } catch (ServiceException e) {
            log.error("[微信支付分] 查询退款业务异常: code={}, msg={}", e.getErrorCode(), e.getErrorMessage(), e);
            return PayScoreResult.fail(e.getErrorCode(), e.getErrorMessage());
        } catch (MalformedMessageException e) {
            log.error("[微信支付分] 查询退款消息解析异常: {}", e.getMessage(), e);
            return PayScoreResult.fail("MESSAGE_ERROR", "消息解析异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("[微信支付分] 查询退款未知异常", e);
            return PayScoreResult.fail("UNKNOWN_ERROR", "查询退款失败: " + e.getMessage());
        }
    }

    @Override
    public PayScoreCallbackResult parseCallback(Map<String, Object> params) {
        log.info("[微信支付分] 解析回调通知 - 参数Keys: {}", params.keySet());

        // 检查服务可用性
        if (wxNotificationParser == null) {
            log.error("[微信支付分] 回调解析服务未初始化，请检查微信支付配置");
            return PayScoreCallbackResult.fail("回调解析服务未初始化，请检查配置");
        }

        try {
            // 从 params 中提取微信 V3 回调所需的信息
            String timestamp = (String) params.get("Wechatpay-Timestamp");
            String nonce = (String) params.get("Wechatpay-Nonce");
            String signature = (String) params.get("Wechatpay-Signature");
            String serial = (String) params.get("Wechatpay-Serial");
            String signType = (String) params.getOrDefault("Wechatpay-Signature-Type", "WECHATPAY2-SHA256-RSA2048");
            String body = (String) params.get("body");

            log.debug("[微信支付分] 回调请求头: timestamp={}, nonce={}, serial={}, signType={}",
                    timestamp, nonce, serial, signType);

            // 构建 RequestParam
            RequestParam requestParam = new RequestParam.Builder()
                    .serialNumber(serial)
                    .nonce(nonce)
                    .timestamp(timestamp)
                    .signature(signature)
                    .signType(signType)
                    .body(body)
                    .build();

            // SDK 自动完成签名验证 + AES-256-GCM 解密
            // 解密后是 JSON 对象，用 Jackson 序列化获取 JSON 字符串
            Object decryptedData = wxNotificationParser.parse(requestParam, Object.class);
            String decryptedJson = objectMapper.writeValueAsString(decryptedData);
            log.info("[微信支付分] 回调解密数据: {}", decryptedJson);

            // 解析 JSON
            JsonNode dataJson = objectMapper.readTree(decryptedJson);

            // 从外层 body 获取 event_type（回调通知外层结构）
            String eventType = null;
            try {
                JsonNode outerBody = objectMapper.readTree(body);
                eventType = getJsonString(outerBody, "event_type");
            } catch (Exception e) {
                log.warn("[微信支付分] 解析外层body获取event_type失败: {}", e.getMessage());
            }

            // 如果外层没有，尝试从解密数据中获取
            if (eventType == null && dataJson.has("event_type")) {
                eventType = getJsonString(dataJson, "event_type");
            }

            String outOrderNo = getJsonString(dataJson, "out_order_no");
            String state = getJsonString(dataJson, "state");
            String openId = getJsonString(dataJson, "openid");

            PayScoreCallbackResult result = PayScoreCallbackResult.success(eventType, outOrderNo, state);
            result.setOpenId(openId);

            // 解析总金额
            if (dataJson.has("total_amount") && !dataJson.get("total_amount").isNull()) {
                int totalAmountFen = dataJson.get("total_amount").asInt();
                result.setTotalAmount(fenToYuan(totalAmountFen));
            }

            // 提取微信支付订单号（用于退款）
            if (dataJson.has("collection")) {
                JsonNode collection = dataJson.get("collection");
                if (collection.has("details") && collection.get("details").isArray()) {
                    JsonNode details = collection.get("details");
                    if (details.size() > 0) {
                        String transactionId = getJsonString(details.get(0), "transaction_id");
                        result.setTransactionId(transactionId);
                    }
                }
            }

            // 解析支付时间
            if (dataJson.has("pay_succ_time") && !dataJson.get("pay_succ_time").isNull()) {
                String paySuccTime = dataJson.get("pay_succ_time").asText();
                result.setPayTime(parsePayTime(paySuccTime));
            }

            // 解析取消原因
            if (dataJson.has("cancel_reason") && !dataJson.get("cancel_reason").isNull()) {
                result.setCancelReason(dataJson.get("cancel_reason").asText());
            }

            log.info("[微信支付分] 回调解析成功 - eventType: {}, outOrderNo: {}, state: {}, openId: {}, amount: {}元",
                    eventType, outOrderNo, state, openId, result.getTotalAmount());
            return result;

        } catch (ValidationException e) {
            log.error("[微信支付分] 回调签名验证失败: {}", e.getMessage(), e);
            return PayScoreCallbackResult.fail("签名验证失败: " + e.getMessage());
        } catch (MalformedMessageException e) {
            log.error("[微信支付分] 回调消息解析失败: {}", e.getMessage(), e);
            return PayScoreCallbackResult.fail("消息解析失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("[微信支付分] 回调处理未知异常", e);
            return PayScoreCallbackResult.fail("回调处理失败: " + e.getMessage());
        }
    }

    // ==================== 私有辅助方法 ====================

    /**
     * 检查服务可用性
     */
    private PayScoreResult checkServiceAvailable() {
        if (wxPayHttpClient == null) {
            log.error("[微信支付分] HTTP客户端未初始化，请检查微信支付配置");
            return PayScoreResult.fail("SERVICE_UNAVAILABLE", "支付分服务未配置，HTTP客户端未初始化");
        }
        if (wxPayConfig == null) {
            log.error("[微信支付分] 支付配置未初始化");
            return PayScoreResult.fail("CONFIG_UNAVAILABLE", "支付分服务未配置");
        }
        if (wxPayConfig.getServiceId() == null || wxPayConfig.getServiceId().isEmpty()) {
            log.error("[微信支付分] 支付分服务ID未配置");
            return PayScoreResult.fail("CONFIG_ERROR", "支付分服务ID未配置");
        }
        return null;
    }

    /**
     * 元转分
     */
    private int yuanToFen(BigDecimal yuan) {
        if (yuan == null) {
            return 0;
        }
        return yuan.multiply(PaymentConstants.YUAN_TO_FEN).intValue();
    }

    /**
     * 分转元
     */
    private BigDecimal fenToYuan(int fen) {
        return BigDecimal.valueOf(fen).divide(PaymentConstants.YUAN_TO_FEN, 2, RoundingMode.HALF_UP);
    }

    /**
     * 安全获取 JSON 字符串值
     */
    private String getJsonString(JsonNode json, String key) {
        if (json.has(key) && !json.get(key).isNull()) {
            return json.get(key).asText();
        }
        return null;
    }

    /**
     * 解析支付时间
     */
    private LocalDateTime parsePayTime(String timeStr) {
        if (timeStr == null || timeStr.isEmpty()) {
            return null;
        }
        try {
            // 微信返回的时间格式: 2018-06-08T10:34:56+08:00 (ISO 8601)
            OffsetDateTime offsetDateTime = OffsetDateTime.parse(timeStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
            return offsetDateTime.toLocalDateTime();
        } catch (Exception e) {
            log.warn("[微信支付分] 支付时间解析失败: {}, 使用当前时间", timeStr);
            return LocalDateTime.now();
        }
    }
}
