using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Xml;
using HoneyBox.Core.Interfaces;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using HoneyBox.Model.Models.Auth;
using HoneyBox.Model.Models.Payment;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace HoneyBox.Core.Services;

/// <summary>
/// 微信支付服务实现
/// </summary>
public class WechatPayService : IWechatPayService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly HttpClient _httpClient;
    private readonly ILogger<WechatPayService> _logger;
    private readonly IWechatPayConfigService _configService;
    private readonly IWechatService _wechatService;
    private readonly IRedisService _redisService;
    private readonly WechatPaySettings _settings;
    private readonly AppSettings _appSettings;
    private readonly Lazy<IWechatPayV3Service>? _v3ServiceLazy;

    /// <summary>
    /// 微信统一下单API地址
    /// </summary>
    private const string UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    /// <summary>
    /// 微信发货通知API地址
    /// </summary>
    private const string SHIPPING_NOTIFY_URL = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info";

    /// <summary>
    /// 发货失败订单Redis键前缀
    /// </summary>
    private const string FAILED_SHIPPING_KEY_PREFIX = "post_order:";

    /// <summary>
    /// 发货失败订单Redis过期时间（3天）
    /// </summary>
    private static readonly TimeSpan FAILED_SHIPPING_EXPIRY = TimeSpan.FromDays(3);

    /// <summary>
    /// 测试用户支付金额（分）
    /// </summary>
    private const int TEST_USER_PAY_AMOUNT = 1; // 0.01元 = 1分

    public WechatPayService(
        HoneyBoxDbContext dbContext,
        HttpClient httpClient,
        ILogger<WechatPayService> logger,
        IWechatPayConfigService configService,
        IWechatService wechatService,
        IRedisService redisService,
        IOptions<WechatPaySettings> settings,
        AppSettings appSettings,
        Lazy<IWechatPayV3Service>? v3ServiceLazy = null)
    {
        _dbContext = dbContext;
        _httpClient = httpClient;
        _logger = logger;
        _configService = configService;
        _wechatService = wechatService;
        _redisService = redisService;
        _settings = settings.Value;
        _appSettings = appSettings;
        _v3ServiceLazy = v3ServiceLazy;
    }

    /// <inheritdoc />
    public async Task<WechatPayResult> CreatePaymentAsync(WechatPayRequest request)
    {
        try
        {
            _logger.LogInformation("开始创建微信支付订单: OrderNo={OrderNo}, UserId={UserId}, Amount={Amount}",
                request.OrderNo, request.UserId, request.Amount);

            // 1. 根据订单号获取商户配置，检查支付版本
            var merchantConfig = _configService.GetMerchantByOrderNo(request.OrderNo);
            
            // 2. 版本路由：如果配置为 V3 且 V3 服务可用，则使用 V3 服务
            if (merchantConfig.PayVersion == "V3" && _v3ServiceLazy != null)
            {
                _logger.LogInformation("商户配置为 V3 版本，路由到 V3 服务: MchId={MchId}", merchantConfig.MchId);
                return await _v3ServiceLazy.Value.CreateJsapiOrderAsync(request);
            }

            // 3. 使用 V2 流程
            _logger.LogDebug("使用 V2 支付流程: MchId={MchId}, PayVersion={PayVersion}", 
                merchantConfig.MchId, merchantConfig.PayVersion);

            // 4. 获取用户信息和OpenId
            var user = await _dbContext.Users.FirstOrDefaultAsync(u => u.Id == request.UserId);
            if (user == null)
            {
                _logger.LogWarning("用户不存在: UserId={UserId}", request.UserId);
                return new WechatPayResult
                {
                    Status = 0,
                    Msg = "用户不存在"
                };
            }

            var openId = string.IsNullOrEmpty(request.OpenId) ? user.OpenId : request.OpenId;
            if (string.IsNullOrEmpty(openId))
            {
                _logger.LogWarning("用户OpenId为空: UserId={UserId}", request.UserId);
                return new WechatPayResult
                {
                    Status = 0,
                    Msg = "用户OpenId不存在"
                };
            }

            // 5. 使用已获取的商户配置
            var appId = merchantConfig.AppId;
            var mchId = merchantConfig.MchId;
            var merchantKey = merchantConfig.Key;

            _logger.LogDebug("使用商户配置: MchId={MchId}, AppId={AppId}", mchId, appId);

            // 3. 生成随机字符串
            var nonceStr = GenerateNonceStr();
            var callbackNonceStr = GenerateNonceStr();

            // 4. 生成回调通知URL
            var notifyUrl = GenerateNotifyUrl(request.Attach, request.UserId, request.OrderNo, callbackNonceStr);

            // 5. 保存通知记录到order_notify表
            await SaveOrderNotifyAsync(request.OrderNo, notifyUrl, callbackNonceStr, request.Amount, request.Attach, openId);

            // 6. 构建统一下单参数
            var body = TruncateBody(request.Body, 30);
            var totalFee = (int)Math.Round(request.Amount * 100); // 转换为分

            // 测试环境下，IsTest=2 的用户支付金额改为 0.01 元
            if (_appSettings.IsTestEnvironment && user.IsTest == 2)
            {
                _logger.LogInformation("测试用户支付金额调整: UserId={UserId}, 原金额={OriginalAmount}分, 调整为={TestAmount}分",
                    request.UserId, totalFee, TEST_USER_PAY_AMOUNT);
                totalFee = TEST_USER_PAY_AMOUNT;
            }

            var unifiedOrderParams = new Dictionary<string, string>
            {
                { "appid", appId },
                { "mch_id", mchId },
                { "nonce_str", nonceStr },
                { "body", body },
                { "attach", request.Attach },
                { "out_trade_no", request.OrderNo },
                { "notify_url", notifyUrl },
                { "total_fee", totalFee.ToString() },
                { "spbill_create_ip", GetClientIp() },
                { "trade_type", "JSAPI" },
                { "openid", openId }
            };

            // 7. 生成签名
            unifiedOrderParams["sign"] = MakeSign(unifiedOrderParams, merchantKey);

            // 8. 转换为XML并调用微信API
            var requestXml = DictionaryToXml(unifiedOrderParams);
            _logger.LogDebug("统一下单请求XML: {Xml}", requestXml);

            var responseXml = await PostXmlAsync(UNIFIED_ORDER_URL, requestXml);
            _logger.LogDebug("统一下单响应XML: {Xml}", responseXml);

            // 9. 解析响应
            var responseData = XmlToDictionary(responseXml);
            if (responseData == null)
            {
                _logger.LogError("解析微信响应失败");
                return new WechatPayResult
                {
                    Status = 0,
                    Msg = "网络故障，请稍后重试(解析响应失败)"
                };
            }

            // 10. 检查返回结果
            if (!responseData.TryGetValue("return_code", out var returnCode) || returnCode != "SUCCESS")
            {
                var returnMsg = responseData.GetValueOrDefault("return_msg", "未知错误");
                _logger.LogWarning("统一下单失败: return_code={ReturnCode}, return_msg={ReturnMsg}", returnCode, returnMsg);
                return new WechatPayResult
                {
                    Status = 0,
                    Msg = $"网络故障，请稍后重试({returnMsg})"
                };
            }

            if (!responseData.TryGetValue("result_code", out var resultCode) || resultCode != "SUCCESS")
            {
                var errCode = responseData.GetValueOrDefault("err_code", "");
                var errCodeDes = responseData.GetValueOrDefault("err_code_des", "未知错误");
                _logger.LogWarning("统一下单业务失败: err_code={ErrCode}, err_code_des={ErrCodeDes}", errCode, errCodeDes);
                return new WechatPayResult
                {
                    Status = 0,
                    Msg = $"支付失败({GetErrorMessage(errCode, errCodeDes)})"
                };
            }

            // 11. 获取prepay_id
            if (!responseData.TryGetValue("prepay_id", out var prepayId) || string.IsNullOrEmpty(prepayId))
            {
                _logger.LogError("统一下单成功但prepay_id为空");
                return new WechatPayResult
                {
                    Status = 0,
                    Msg = "网络故障，请稍后重试(prepay_id为空)"
                };
            }

            // 12. 构建返回给前端的支付参数
            var timeStamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
            var payNonceStr = GenerateNonceStr();

            var payParams = new Dictionary<string, string>
            {
                { "appId", appId },
                { "timeStamp", timeStamp },
                { "nonceStr", payNonceStr },
                { "package", $"prepay_id={prepayId}" },
                { "signType", "MD5" }
            };

            // 13. 生成支付签名
            var paySign = MakeSign(payParams, merchantKey);

            _logger.LogInformation("微信支付订单创建成功: OrderNo={OrderNo}, PrepayId={PrepayId}", request.OrderNo, prepayId);

            return new WechatPayResult
            {
                Status = 1,
                Msg = "success",
                Data = new WechatPayData
                {
                    AppId = appId,
                    TimeStamp = timeStamp,
                    NonceStr = payNonceStr,
                    Package = $"prepay_id={prepayId}",
                    SignType = "MD5",
                    PaySign = paySign,
                    IsWeixin = 1
                }
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建微信支付订单异常: OrderNo={OrderNo}", request.OrderNo);
            return new WechatPayResult
            {
                Status = 0,
                Msg = "系统错误，请稍后重试"
            };
        }
    }

    /// <summary>
    /// 生成回调通知URL
    /// </summary>
    private string GenerateNotifyUrl(string attach, int userId, string orderNo, string nonceStr)
    {
        // 使用配置的基础URL，如果没有配置则使用默认格式
        var baseUrl = _settings.NotifyBaseUrl;
        if (string.IsNullOrEmpty(baseUrl))
        {
            // 默认回调URL格式
            return $"/api/notify/order_notify";
        }

        // 生成带参数的回调URL（与PHP保持一致）
        return $"{baseUrl.TrimEnd('/')}/api/notify/{attach}/{userId}/{orderNo}/{nonceStr}";
    }

    /// <summary>
    /// 保存订单通知记录
    /// </summary>
    private async Task SaveOrderNotifyAsync(string orderNo, string notifyUrl, string nonceStr, decimal amount, string attach, string openId)
    {
        var orderNotify = new OrderNotify
        {
            OrderNo = orderNo,
            NotifyUrl = notifyUrl,
            NonceStr = nonceStr,
            PayTime = DateTime.Now,
            PayAmount = amount,
            Status = 0,
            RetryCount = 0,
            Attach = attach,
            OpenId = openId,
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now
        };

        _dbContext.OrderNotifies.Add(orderNotify);
        await _dbContext.SaveChangesAsync();

        _logger.LogDebug("保存订单通知记录: OrderNo={OrderNo}, NotifyUrl={NotifyUrl}", orderNo, notifyUrl);
    }

    /// <summary>
    /// 截断商品描述（微信限制最大长度）
    /// </summary>
    private static string TruncateBody(string body, int maxLength)
    {
        if (string.IsNullOrEmpty(body))
        {
            return "商品购买";
        }

        // 使用字符数而不是字节数
        if (body.Length <= maxLength)
        {
            return body;
        }

        return body.Substring(0, maxLength);
    }

    /// <summary>
    /// 生成32位随机字符串
    /// </summary>
    private static string GenerateNonceStr(int length = 32)
    {
        const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        var random = new Random();
        var result = new char[length];

        for (int i = 0; i < length; i++)
        {
            result[i] = chars[random.Next(chars.Length)];
        }

        return new string(result);
    }

    /// <summary>
    /// 获取客户端IP
    /// </summary>
    private static string GetClientIp()
    {
        // 在实际环境中应该从HttpContext获取
        // 这里返回默认值，实际使用时需要通过依赖注入获取IHttpContextAccessor
        return "127.0.0.1";
    }

    /// <summary>
    /// 将字典转换为XML
    /// </summary>
    private static string DictionaryToXml(Dictionary<string, string> parameters)
    {
        var sb = new StringBuilder();
        sb.Append("<xml>");

        foreach (var kvp in parameters)
        {
            if (string.IsNullOrEmpty(kvp.Value))
            {
                continue;
            }

            // 数字类型不需要CDATA
            if (int.TryParse(kvp.Value, out _) || decimal.TryParse(kvp.Value, out _))
            {
                sb.Append($"<{kvp.Key}>{kvp.Value}</{kvp.Key}>");
            }
            else
            {
                sb.Append($"<{kvp.Key}><![CDATA[{kvp.Value}]]></{kvp.Key}>");
            }
        }

        sb.Append("</xml>");
        return sb.ToString();
    }

    /// <summary>
    /// 将XML转换为字典
    /// </summary>
    private static Dictionary<string, string>? XmlToDictionary(string xml)
    {
        if (string.IsNullOrEmpty(xml))
        {
            return null;
        }

        try
        {
            var doc = new XmlDocument();
            doc.LoadXml(xml);

            var root = doc.DocumentElement;
            if (root == null)
            {
                return null;
            }

            var result = new Dictionary<string, string>();
            foreach (XmlNode node in root.ChildNodes)
            {
                if (node.NodeType == XmlNodeType.Element)
                {
                    result[node.Name] = node.InnerText;
                }
            }

            return result;
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// 发送XML POST请求
    /// </summary>
    private async Task<string> PostXmlAsync(string url, string xml, int timeout = 30)
    {
        try
        {
            var content = new StringContent(xml, Encoding.UTF8, "application/xml");
            
            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeout));
            var response = await _httpClient.PostAsync(url, content, cts.Token);
            
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发送XML请求失败: Url={Url}", url);
            throw;
        }
    }

    /// <summary>
    /// 获取错误消息
    /// </summary>
    private static string GetErrorMessage(string errCode, string errCodeDes)
    {
        var errorMessages = new Dictionary<string, string>
        {
            { "NOAUTH", "商户未开通此接口权限" },
            { "NOTENOUGH", "用户帐号余额不足" },
            { "ORDERNOTEXIST", "订单号不存在" },
            { "ORDERPAID", "商户订单已支付，无需重复操作" },
            { "ORDERCLOSED", "当前订单已关闭，无法支付" },
            { "SYSTEMERROR", "系统错误!系统超时" },
            { "APPID_NOT_EXIST", "参数中缺少APPID" },
            { "MCHID_NOT_EXIST", "参数中缺少MCHID" },
            { "APPID_MCHID_NOT_MATCH", "appid和mch_id不匹配" },
            { "LACK_PARAMS", "缺少必要的请求参数" },
            { "OUT_TRADE_NO_USED", "同一笔交易不能多次提交" },
            { "SIGNERROR", "参数签名结果不正确" },
            { "XML_FORMAT_ERROR", "XML格式错误" },
            { "REQUIRE_POST_METHOD", "未使用post传递参数" },
            { "POST_DATA_EMPTY", "post数据不能为空" },
            { "NOT_UTF8", "未使用指定编码格式" }
        };

        if (!string.IsNullOrEmpty(errCode) && errorMessages.TryGetValue(errCode, out var message))
        {
            return message;
        }

        return errCodeDes;
    }

    /// <inheritdoc />
    public bool VerifySign(Dictionary<string, string> parameters, string sign, string? merchantKey = null)
    {
        if (string.IsNullOrEmpty(sign))
        {
            _logger.LogWarning("签名验证失败：签名为空");
            return false;
        }

        var calculatedSign = MakeSign(parameters, merchantKey);
        var isValid = string.Equals(calculatedSign, sign, StringComparison.OrdinalIgnoreCase);

        if (!isValid)
        {
            _logger.LogWarning("签名验证失败：计算签名={CalculatedSign}，传入签名={Sign}", calculatedSign, sign);
        }

        return isValid;
    }

    /// <inheritdoc />
    public string MakeSign(Dictionary<string, string> parameters, string? merchantKey = null)
    {
        // 获取商户密钥
        var key = merchantKey ?? _settings.DefaultMerchant.Key;

        // 签名步骤一：按字典序排序数组参数（ASCII码从小到大）
        // 过滤掉空值和sign字段
        var sortedParams = parameters
            .Where(p => !string.IsNullOrEmpty(p.Value) && !string.Equals(p.Key, "sign", StringComparison.OrdinalIgnoreCase))
            .OrderBy(p => p.Key, StringComparer.Ordinal)
            .ToList();

        // 签名步骤二：将参数拼接为URL格式 key=value&key=value
        var urlParams = ToUrlParams(sortedParams);

        // 签名步骤三：在string后加入KEY
        var signString = $"{urlParams}&key={key}";

        // 签名步骤四：MD5加密
        using var md5 = MD5.Create();
        var hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(signString));

        // 签名步骤五：所有字符转为大写
        return BitConverter.ToString(hashBytes).Replace("-", "").ToUpper();
    }

    /// <summary>
    /// 将参数拼接为URL格式: key=value&key=value
    /// </summary>
    /// <param name="parameters">已排序的参数列表</param>
    /// <returns>URL格式字符串</returns>
    private static string ToUrlParams(IEnumerable<KeyValuePair<string, string>> parameters)
    {
        var parts = parameters.Select(p => $"{p.Key}={p.Value}");
        return string.Join("&", parts);
    }

    /// <summary>
    /// 根据订单号获取商户密钥
    /// </summary>
    /// <param name="orderNo">订单号</param>
    /// <returns>商户密钥</returns>
    public string GetMerchantKeyByOrderNo(string orderNo)
    {
        var merchant = GetMerchantByOrderNo(orderNo);
        return merchant.Key;
    }

    /// <summary>
    /// 验证微信回调签名
    /// </summary>
    /// <param name="notifyData">回调数据</param>
    /// <returns>是否验证通过</returns>
    public bool VerifyNotifySign(WechatNotifyData notifyData)
    {
        // 从回调数据构建参数字典
        var parameters = new Dictionary<string, string>
        {
            { "return_code", notifyData.ReturnCode },
            { "return_msg", notifyData.ReturnMsg },
            { "result_code", notifyData.ResultCode },
            { "appid", notifyData.AppId },
            { "mch_id", notifyData.MchId },
            { "nonce_str", notifyData.NonceStr },
            { "openid", notifyData.OpenId },
            { "trade_type", notifyData.TradeType },
            { "bank_type", notifyData.BankType },
            { "total_fee", notifyData.TotalFee.ToString() },
            { "fee_type", notifyData.FeeType },
            { "cash_fee", notifyData.CashFee.ToString() },
            { "transaction_id", notifyData.TransactionId },
            { "out_trade_no", notifyData.OutTradeNo },
            { "attach", notifyData.Attach },
            { "time_end", notifyData.TimeEnd }
        };

        // 添加可选字段
        if (!string.IsNullOrEmpty(notifyData.ErrCode))
            parameters["err_code"] = notifyData.ErrCode;
        if (!string.IsNullOrEmpty(notifyData.ErrCodeDes))
            parameters["err_code_des"] = notifyData.ErrCodeDes;
        if (!string.IsNullOrEmpty(notifyData.SignType))
            parameters["sign_type"] = notifyData.SignType;

        // 根据商户号获取对应的密钥
        var merchantKey = GetMerchantKeyByMchId(notifyData.MchId);

        return VerifySign(parameters, notifyData.Sign, merchantKey);
    }

    /// <summary>
    /// 根据商户号获取商户密钥
    /// </summary>
    /// <param name="mchId">商户号</param>
    /// <returns>商户密钥</returns>
    private string GetMerchantKeyByMchId(string mchId)
    {
        // 先从配置的商户列表中查找
        var merchant = _settings.Merchants.FirstOrDefault(m => m.MchId == mchId);
        if (merchant != null)
        {
            return merchant.Key;
        }

        // 如果没找到，检查默认商户
        if (_settings.DefaultMerchant.MchId == mchId)
        {
            return _settings.DefaultMerchant.Key;
        }

        // 返回默认商户密钥
        _logger.LogWarning("未找到商户号 {MchId} 的配置，使用默认商户密钥", mchId);
        return _settings.DefaultMerchant.Key;
    }

    /// <inheritdoc />
    public async Task<OrderShippingNotifyResult> PostOrderShippingAsync(OrderShippingNotifyRequest request)
    {
        try
        {
            _logger.LogInformation("开始发送订单发货通知: OrderNo={OrderNo}, OpenId={OpenId}", 
                request.OrderNo, request.OpenId);

            // 1. 根据订单号获取商户配置
            var merchantConfig = _configService.GetMerchantByOrderNo(request.OrderNo);
            var mchId = merchantConfig.MchId;
            var appId = merchantConfig.AppId;

            _logger.LogDebug("使用商户配置: MchId={MchId}, AppId={AppId}", mchId, appId);

            // 2. 获取access_token
            var accessToken = await _wechatService.GetAccessTokenAsync(appId);
            if (string.IsNullOrEmpty(accessToken))
            {
                _logger.LogError("获取access_token失败: AppId={AppId}", appId);
                
                // 存入重试队列
                await SaveFailedShippingOrderAsync(request, merchantConfig, -1, "获取access_token失败");
                
                return new OrderShippingNotifyResult
                {
                    Success = false,
                    ErrCode = -1,
                    ErrMsg = "获取access_token失败",
                    QueuedForRetry = true
                };
            }

            // 3. 构建发货通知消息
            var itemDesc = GetShippingItemDesc(request);

            // 4. 构建请求参数
            var uploadTime = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00";
            var requestBody = new
            {
                order_key = new
                {
                    order_number_type = 1, // 使用商户订单号
                    mchid = mchId,
                    out_trade_no = request.OrderNo
                },
                logistics_type = request.LogisticsType, // 物流类型：4=虚拟商品
                delivery_mode = request.DeliveryMode, // 发货模式：1=统一发货
                shipping_list = new[]
                {
                    new
                    {
                        item_desc = itemDesc
                    }
                },
                upload_time = uploadTime,
                payer = new
                {
                    openid = request.OpenId
                }
            };

            var requestJson = JsonSerializer.Serialize(requestBody);

            // 5. 记录请求日志
            _logger.LogDebug("发货通知请求: OrderNo={OrderNo}, MchId={MchId}, Request={Request}", 
                request.OrderNo, mchId, requestJson);

            // 6. 调用微信API
            var requestUrl = $"{SHIPPING_NOTIFY_URL}?access_token={accessToken}";
            var content = new StringContent(requestJson, Encoding.UTF8, "application/json");
            
            var response = await _httpClient.PostAsync(requestUrl, content);
            var responseContent = await response.Content.ReadAsStringAsync();

            // 7. 记录响应日志
            _logger.LogDebug("发货通知响应: OrderNo={OrderNo}, Response={Response}", 
                request.OrderNo, responseContent);

            // 8. 解析响应
            using var jsonDoc = JsonDocument.Parse(responseContent);
            var root = jsonDoc.RootElement;

            var errCode = root.TryGetProperty("errcode", out var errCodeProp) ? errCodeProp.GetInt32() : -1;
            var errMsg = root.TryGetProperty("errmsg", out var errMsgProp) ? errMsgProp.GetString() ?? "unknown" : "unknown";

            // 9. 判断结果
            if (errCode == 0 && errMsg == "ok")
            {
                _logger.LogInformation("发货通知成功: OrderNo={OrderNo}", request.OrderNo);
                return new OrderShippingNotifyResult
                {
                    Success = true,
                    ErrCode = 0,
                    ErrMsg = "ok"
                };
            }
            else
            {
                _logger.LogWarning("发货通知失败: OrderNo={OrderNo}, ErrCode={ErrCode}, ErrMsg={ErrMsg}", 
                    request.OrderNo, errCode, errMsg);

                // 存入重试队列
                await SaveFailedShippingOrderAsync(request, merchantConfig, errCode, errMsg);

                return new OrderShippingNotifyResult
                {
                    Success = false,
                    ErrCode = errCode,
                    ErrMsg = errMsg,
                    QueuedForRetry = true
                };
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发货通知异常: OrderNo={OrderNo}", request.OrderNo);

            // 尝试存入重试队列
            try
            {
                var merchantConfig = _configService.GetMerchantByOrderNo(request.OrderNo);
                await SaveFailedShippingOrderAsync(request, merchantConfig, -1, ex.Message);
            }
            catch (Exception saveEx)
            {
                _logger.LogError(saveEx, "保存失败订单到重试队列时发生错误: OrderNo={OrderNo}", request.OrderNo);
            }

            return new OrderShippingNotifyResult
            {
                Success = false,
                ErrCode = -1,
                ErrMsg = ex.Message,
                QueuedForRetry = true
            };
        }
    }

    /// <summary>
    /// 获取发货商品描述
    /// </summary>
    private static string GetShippingItemDesc(OrderShippingNotifyRequest request)
    {
        // 如果请求中指定了描述，直接使用
        if (!string.IsNullOrEmpty(request.ItemDesc))
        {
            return request.ItemDesc;
        }

        // 根据订单前缀判断消息内容
        if (request.OrderNo.StartsWith("FH_"))
        {
            // 发货订单
            return "本单购买的商品正在打包，请联系客服获取物流信息";
        }
        else
        {
            // 虚拟商品（抽奖等）
            return "本单购买商品已发放至[小程序盒柜]";
        }
    }

    /// <summary>
    /// 保存发货失败的订单到Redis重试队列
    /// </summary>
    private async Task SaveFailedShippingOrderAsync(
        OrderShippingNotifyRequest request, 
        WechatPayMerchantConfig merchantConfig,
        int errorCode, 
        string errorMsg)
    {
        try
        {
            var key = $"{FAILED_SHIPPING_KEY_PREFIX}{request.OrderNo}";
            var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

            var failedOrder = new FailedShippingOrderData
            {
                OpenId = request.OpenId,
                AppId = merchantConfig.AppId,
                OrderNo = request.OrderNo,
                MchId = merchantConfig.MchId,
                ItemDesc = GetShippingItemDesc(request),
                ErrorCode = errorCode,
                ErrorMsg = errorMsg,
                RetryCount = 0,
                LastRetryTime = now,
                CreateTime = now
            };

            var json = JsonSerializer.Serialize(failedOrder);
            await _redisService.SetStringAsync(key, json, FAILED_SHIPPING_EXPIRY);

            _logger.LogInformation("已将发货失败订单存入重试队列: OrderNo={OrderNo}, Key={Key}", 
                request.OrderNo, key);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "保存发货失败订单到Redis时发生错误: OrderNo={OrderNo}", request.OrderNo);
            throw;
        }
    }

    /// <inheritdoc />
    public WechatPayMerchantConfig GetMerchantByOrderNo(string orderNo)
    {
        // 使用配置服务获取商户配置
        return _configService.GetMerchantByOrderNo(orderNo);
    }

    /// <inheritdoc />
    public WechatNotifyData ParseNotifyXml(string xmlData)
    {
        var result = new WechatNotifyData();

        try
        {
            var doc = new XmlDocument();
            doc.LoadXml(xmlData);

            var root = doc.DocumentElement;
            if (root == null) return result;

            result.ReturnCode = GetXmlNodeValue(root, "return_code");
            result.ReturnMsg = GetXmlNodeValue(root, "return_msg");
            result.ResultCode = GetXmlNodeValue(root, "result_code");
            result.ErrCode = GetXmlNodeValue(root, "err_code");
            result.ErrCodeDes = GetXmlNodeValue(root, "err_code_des");
            result.AppId = GetXmlNodeValue(root, "appid");
            result.MchId = GetXmlNodeValue(root, "mch_id");
            result.NonceStr = GetXmlNodeValue(root, "nonce_str");
            result.Sign = GetXmlNodeValue(root, "sign");
            result.SignType = GetXmlNodeValue(root, "sign_type");
            result.OpenId = GetXmlNodeValue(root, "openid");
            result.TradeType = GetXmlNodeValue(root, "trade_type");
            result.BankType = GetXmlNodeValue(root, "bank_type");
            result.FeeType = GetXmlNodeValue(root, "fee_type");
            result.TransactionId = GetXmlNodeValue(root, "transaction_id");
            result.OutTradeNo = GetXmlNodeValue(root, "out_trade_no");
            result.Attach = GetXmlNodeValue(root, "attach");
            result.TimeEnd = GetXmlNodeValue(root, "time_end");

            // 解析金额（单位：分）
            if (int.TryParse(GetXmlNodeValue(root, "total_fee"), out var totalFee))
            {
                result.TotalFee = totalFee;
            }
            if (int.TryParse(GetXmlNodeValue(root, "cash_fee"), out var cashFee))
            {
                result.CashFee = cashFee;
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "解析微信回调XML失败: {XmlData}", xmlData);
        }

        return result;
    }

    /// <inheritdoc />
    public string GenerateNotifyResponseXml(string returnCode, string returnMsg)
    {
        return $"<xml><return_code><![CDATA[{returnCode}]]></return_code><return_msg><![CDATA[{returnMsg}]]></return_msg></xml>";
    }

    private static string GetXmlNodeValue(XmlElement root, string nodeName)
    {
        var node = root.SelectSingleNode(nodeName);
        return node?.InnerText ?? string.Empty;
    }
}
