package com.gxwebsoft.test;

import com.gxwebsoft.common.core.config.CertificateProperties;
import com.gxwebsoft.common.core.service.PaymentCacheService;
import com.gxwebsoft.common.core.utils.CertificateLoader;
import com.gxwebsoft.common.core.utils.WechatCertAutoConfig;
import com.gxwebsoft.common.system.entity.Payment;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAPublicKeyConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * 微信支付公钥配置测试
 * 
 * @author 科技小王子
 * @since 2025-07-29
 */
@SpringBootTest
public class WechatPayPublicKeyTest {

    @Autowired
    private PaymentCacheService paymentCacheService;
    
    @Autowired
    private CertificateLoader certificateLoader;
    
    @Autowired
    private CertificateProperties certConfig;
    
    @Autowired
    private WechatCertAutoConfig wechatCertAutoConfig;

    @Test
    public void testPublicKeyConfiguration() {
        try {
            System.out.println("=== 微信支付公钥配置测试 ===");
            
            // 测试租户ID
            Integer tenantId = 10547;
            
            // 获取支付配置
            Payment payment = paymentCacheService.getWechatPayConfig(tenantId);
            System.out.println("支付配置获取成功:");
            System.out.println("商户号: " + payment.getMchId());
            System.out.println("应用ID: " + payment.getAppId());
            System.out.println("序列号: " + payment.getMerchantSerialNumber());
            System.out.println("API密钥: " + (payment.getApiKey() != null ? "已配置(长度:" + payment.getApiKey().length() + ")" : "未配置"));
            System.out.println("公钥文件: " + payment.getPubKey());
            System.out.println("公钥ID: " + payment.getPubKeyId());
            
            // 测试证书文件加载
            String tenantCertPath = "dev/wechat/" + tenantId;
            String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile();
            
            System.out.println("\n=== 证书文件检查 ===");
            System.out.println("私钥路径: " + privateKeyPath);
            
            if (certificateLoader.certificateExists(privateKeyPath)) {
                String privateKey = certificateLoader.loadCertificatePath(privateKeyPath);
                System.out.println("✅ 私钥文件加载成功: " + privateKey);
                
                // 检查是否配置了公钥
                if (payment.getPubKey() != null && !payment.getPubKey().isEmpty() && 
                    payment.getPubKeyId() != null && !payment.getPubKeyId().isEmpty()) {
                    
                    System.out.println("\n=== 公钥配置测试 ===");
                    String pubKeyPath = tenantCertPath + "/" + payment.getPubKey();
                    System.out.println("公钥路径: " + pubKeyPath);
                    
                    if (certificateLoader.certificateExists(pubKeyPath)) {
                        String pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath);
                        System.out.println("✅ 公钥文件加载成功: " + pubKeyFile);
                        
                        // 测试RSA公钥配置
                        try {
                            Config config = new RSAPublicKeyConfig.Builder()
                                .merchantId(payment.getMchId())
                                .privateKeyFromPath(privateKey)
                                .publicKeyFromPath(pubKeyFile)
                                .publicKeyId(payment.getPubKeyId())
                                .merchantSerialNumber(payment.getMerchantSerialNumber())
                                .apiV3Key(payment.getApiKey())
                                .build();
                            
                            System.out.println("✅ RSA公钥配置创建成功");
                            System.out.println("配置类型: " + config.getClass().getSimpleName());
                            
                        } catch (Exception e) {
                            System.err.println("❌ RSA公钥配置失败: " + e.getMessage());
                            e.printStackTrace();
                        }
                        
                    } else {
                        System.err.println("❌ 公钥文件不存在: " + pubKeyPath);
                        System.out.println("💡 建议: 请将公钥文件放置到指定位置");
                    }
                    
                } else {
                    System.out.println("\n⚠️ 未配置公钥信息");
                    System.out.println("💡 建议: 在数据库中配置 pubKey 和 pubKeyId 字段");
                    
                    // 测试自动证书配置
                    System.out.println("\n=== 自动证书配置测试 ===");
                    try {
                        Config autoConfig = wechatCertAutoConfig.createAutoConfig(
                            payment.getMchId(),
                            privateKey,
                            payment.getMerchantSerialNumber(),
                            payment.getApiKey()
                        );
                        System.out.println("✅ 自动证书配置创建成功");
                        System.out.println("配置类型: " + autoConfig.getClass().getSimpleName());
                    } catch (Exception e) {
                        System.err.println("❌ 自动证书配置失败: " + e.getMessage());
                        System.err.println("错误类型: " + e.getClass().getName());
                        
                        if (e.getMessage() != null && e.getMessage().contains("certificate")) {
                            System.err.println("🔍 这是证书相关错误，建议使用公钥模式");
                        }
                    }
                }
                
            } else {
                System.err.println("❌ 私钥文件不存在: " + privateKeyPath);
            }
            
            System.out.println("\n=== 测试完成 ===");
            
        } catch (Exception e) {
            System.err.println("❌ 测试失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    @Test
    public void testCreateSamplePublicKeyConfig() {
        System.out.println("=== 创建示例公钥配置 ===");
        System.out.println("如果您的后台使用公钥模式，请在数据库中配置以下字段:");
        System.out.println("1. pubKey: 公钥文件名，例如 'wechatpay_public_key.pem'");
        System.out.println("2. pubKeyId: 公钥ID，例如 'PUB_KEY_ID_0112422897022025011300326200001208'");
        System.out.println("3. 将公钥文件放置到: src/main/resources/dev/wechat/{tenantId}/");
        System.out.println("\n示例SQL更新语句:");
        System.out.println("UPDATE sys_payment SET ");
        System.out.println("  pub_key = 'wechatpay_public_key.pem',");
        System.out.println("  pub_key_id = 'PUB_KEY_ID_0112422897022025011300326200001208'");
        System.out.println("WHERE tenant_id = 10547 AND type = 0;");
    }
}
