using HoneyBox.Model.Models.Payment;

namespace HoneyBox.Core.Interfaces;

/// <summary>
/// 微信支付 V3 服务接口
/// 提供基于 RSA-SHA256 签名和 AES-256-GCM 加密的 V3 版本支付功能
/// </summary>
public interface IWechatPayV3Service
{
    #region 下单接口

    /// <summary>
    /// 创建 JSAPI 下单（小程序/公众号支付）
    /// </summary>
    /// <param name="request">支付请求</param>
    /// <returns>支付结果，包含调起支付所需参数</returns>
    Task<WechatPayResult> CreateJsapiOrderAsync(WechatPayRequest request);

    #endregion

    #region 订单管理接口

    /// <summary>
    /// 查询订单状态
    /// </summary>
    /// <param name="orderNo">商户订单号</param>
    /// <returns>订单查询结果</returns>
    Task<WechatPayV3QueryResult> QueryOrderAsync(string orderNo);

    /// <summary>
    /// 关闭订单
    /// </summary>
    /// <param name="orderNo">商户订单号</param>
    /// <returns>关闭结果</returns>
    Task<WechatPayV3CloseResult> CloseOrderAsync(string orderNo);

    #endregion

    #region 退款接口

    /// <summary>
    /// 申请退款
    /// </summary>
    /// <param name="request">退款请求</param>
    /// <returns>退款结果</returns>
    Task<WechatPayV3RefundResult> RefundAsync(WechatPayV3RefundRequest request);

    #endregion

    #region 签名与验签

    /// <summary>
    /// 生成 V3 请求签名
    /// </summary>
    /// <param name="method">HTTP 方法（GET、POST 等）</param>
    /// <param name="url">请求 URL（不含域名，如 /v3/pay/transactions/jsapi）</param>
    /// <param name="timestamp">时间戳（秒）</param>
    /// <param name="nonce">随机字符串</param>
    /// <param name="body">请求体（GET 请求为空字符串）</param>
    /// <param name="privateKey">商户私钥（PEM 格式内容）</param>
    /// <returns>Base64 编码的签名字符串</returns>
    string GenerateSignature(string method, string url, string timestamp, string nonce, string body, string privateKey);

    /// <summary>
    /// 验证回调签名
    /// </summary>
    /// <param name="timestamp">微信回调头中的时间戳（Wechatpay-Timestamp）</param>
    /// <param name="nonce">微信回调头中的随机串（Wechatpay-Nonce）</param>
    /// <param name="body">回调请求体</param>
    /// <param name="signature">微信回调头中的签名（Wechatpay-Signature）</param>
    /// <param name="serialNo">微信回调头中的证书序列号（Wechatpay-Serial）</param>
    /// <returns>签名是否有效</returns>
    bool VerifyNotifySignature(string timestamp, string nonce, string body, string signature, string serialNo);

    /// <summary>
    /// 使用指定的公钥验证回调签名
    /// </summary>
    /// <param name="timestamp">时间戳</param>
    /// <param name="nonce">随机串</param>
    /// <param name="body">请求体</param>
    /// <param name="signature">签名</param>
    /// <param name="publicKey">公钥 PEM 内容</param>
    /// <returns>签名是否有效</returns>
    bool VerifyNotifySignatureWithPublicKey(string timestamp, string nonce, string body, string signature, string publicKey);

    #endregion

    #region 加解密

    /// <summary>
    /// 解密回调数据
    /// </summary>
    /// <param name="ciphertext">密文（Base64 编码）</param>
    /// <param name="nonce">随机串</param>
    /// <param name="associatedData">附加数据</param>
    /// <param name="apiV3Key">APIv3 密钥</param>
    /// <returns>解密后的明文 JSON 字符串</returns>
    string DecryptNotifyResource(string ciphertext, string nonce, string associatedData, string apiV3Key);

    /// <summary>
    /// 使用 AES-256-GCM 加密数据（用于测试）
    /// </summary>
    /// <param name="plaintext">明文</param>
    /// <param name="nonce">随机串（12 字节）</param>
    /// <param name="associatedData">附加数据</param>
    /// <param name="apiV3Key">APIv3 密钥（32 字节）</param>
    /// <returns>Base64 编码的密文（包含认证标签）</returns>
    string EncryptNotifyResource(string plaintext, string nonce, string associatedData, string apiV3Key);

    #endregion

    #region 回调格式识别

    /// <summary>
    /// 检测回调数据是否为 V3 格式
    /// V3 格式特征：JSON 格式且包含 resource 字段
    /// </summary>
    /// <param name="notifyBody">回调请求体</param>
    /// <returns>是否为 V3 格式</returns>
    bool IsV3NotifyFormat(string notifyBody);

    /// <summary>
    /// 检测回调数据是否为 V2 格式
    /// V2 格式特征：XML 格式，以 &lt;xml&gt; 开头
    /// </summary>
    /// <param name="notifyBody">回调请求体</param>
    /// <returns>是否为 V2 格式</returns>
    bool IsV2NotifyFormat(string notifyBody);

    /// <summary>
    /// 检测回调格式并返回版本
    /// </summary>
    /// <param name="notifyBody">回调请求体</param>
    /// <returns>回调版本：V3、V2 或 Unknown</returns>
    NotifyVersion DetectNotifyVersion(string notifyBody);

    #endregion

    #region 辅助方法

    /// <summary>
    /// 生成小程序调起支付所需的签名
    /// </summary>
    /// <param name="appId">小程序 AppId</param>
    /// <param name="timestamp">时间戳</param>
    /// <param name="nonceStr">随机字符串</param>
    /// <param name="prepayId">预支付交易会话标识</param>
    /// <param name="privateKey">商户私钥</param>
    /// <returns>支付签名</returns>
    string GeneratePaySign(string appId, string timestamp, string nonceStr, string prepayId, string privateKey);

    /// <summary>
    /// 生成随机字符串
    /// </summary>
    /// <param name="length">长度（默认 32）</param>
    /// <returns>随机字符串</returns>
    string GenerateNonceStr(int length = 32);

    /// <summary>
    /// 获取当前时间戳（秒）
    /// </summary>
    /// <returns>Unix 时间戳字符串</returns>
    string GetTimestamp();

    /// <summary>
    /// 读取私钥文件内容
    /// </summary>
    /// <param name="privateKeyPath">私钥文件路径</param>
    /// <returns>私钥 PEM 内容</returns>
    string ReadPrivateKey(string privateKeyPath);

    /// <summary>
    /// 读取公钥文件内容
    /// </summary>
    /// <param name="publicKeyPath">公钥文件路径</param>
    /// <returns>公钥 PEM 内容</returns>
    string ReadPublicKey(string publicKeyPath);

    #endregion
}
