package com.haha.service.payment.config;

import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAPublicKeyConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.refund.RefundService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.beans.factory.annotation.Autowired;

import jakarta.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * 微信支付 V3 SDK 配置
 * 
 * 通过 wechat.pay.mch-id 配置项控制是否启用
 * 创建 RSAPublicKeyConfig（公钥模式）和核心服务 Bean
 * 初始化失败时不会阻塞应用启动，仅日志警告
 */
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "wechat.pay")
@ConditionalOnProperty(name = "wechat.pay.mch-id")
public class WxPayConfig {

    /** 小程序/公众号 AppID */
    private String appId;
    
    /** 商户号 */
    private String mchId;

    /** API V3 密钥 */
    private String v3ApiKey;

    /** API V2 密钥（32位，用于 openBusinessView 等前端 JSAPI 签名） */
    private String apiV2Key;
    
    /** 支付结果回调通知地址 */
    private String notifyUrl;
    
    /** 商户API私钥文件路径（支持 classpath: 前缀） */
    private String privateKeyPath;
    
    /** 商户API证书序列号 */
    private String merchantSerialNumber;

    /** 支付分服务ID */
    private String serviceId;

    /** 支付分回调通知地址 */
    private String payScoreNotifyUrl;

    /** 微信支付公钥ID（商户平台-API安全-微信支付公钥 处查看） */
    private String wechatPayPublicKeyId;

    /** 微信支付公钥文件路径（支持 classpath: 前缀） */
    private String wechatPayPublicKeyPath;

    @Autowired
    private ResourceLoader resourceLoader;
    
    /**
     * 微信支付 SDK 核心配置
     * 使用 RSAPublicKeyConfig（微信支付公钥模式）
     */
    @Bean
    public Config wxPaySdkConfig() {
        log.info("初始化微信支付 V3 SDK 配置（公钥模式）- 商户号: {}, AppID: {}", mchId, appId);

        try {
            String privateKeyContent = loadPrivateKey();
            String publicKeyContent = loadWechatPayPublicKey();

            Config config = new RSAPublicKeyConfig.Builder()
                    .merchantId(mchId)
                    .privateKey(privateKeyContent)
                    .merchantSerialNumber(merchantSerialNumber)
                    .apiV3Key(v3ApiKey)
                    .publicKeyId(wechatPayPublicKeyId)
                    .publicKey(publicKeyContent)
                    .build();

            log.info("微信支付 V3 SDK 配置初始化成功（公钥模式）");
            return config;
        } catch (Exception e) {
            log.error("微信支付 V3 SDK 配置初始化失败: {}", e.getMessage());
            log.warn("微信支付功能将不可用（应用将继续启动），请检查配置参数和证书文件");
            return null;
        }
    }
    
    /**
     * JSAPI 支付服务（含扩展功能：一步下单+生成支付参数）
     */
    @Bean
    public JsapiServiceExtension jsapiServiceExtension(Config wxPaySdkConfig) {
        if (wxPaySdkConfig == null) {
            log.warn("wxPaySdkConfig 未初始化，JsapiServiceExtension 跳过创建");
            return null;
        }
        return new JsapiServiceExtension.Builder().config(wxPaySdkConfig).build();
    }
    
    /**
     * 退款服务
     */
    @Bean
    public RefundService wxRefundService(Config wxPaySdkConfig) {
        if (wxPaySdkConfig == null) {
            log.warn("wxPaySdkConfig 未初始化，RefundService 跳过创建");
            return null;
        }
        return new RefundService.Builder().config(wxPaySdkConfig).build();
    }
    
    /**
     * 回调通知解析器（含签名验证+AES-256-GCM 解密）
     */
    @Bean
    public NotificationParser wxNotificationParser(Config wxPaySdkConfig) {
        if (wxPaySdkConfig == null) {
            log.warn("wxPaySdkConfig 未初始化，NotificationParser 跳过创建");
            return null;
        }
        return new NotificationParser((NotificationConfig) wxPaySdkConfig);
    }
    
    /**
     * 读取微信支付公钥文件内容
     */
    private String loadWechatPayPublicKey() throws IOException {
        if (wechatPayPublicKeyPath == null || wechatPayPublicKeyPath.isEmpty()) {
            throw new IOException("微信支付公钥路径未配置");
        }
        Resource resource = resourceLoader.getResource(wechatPayPublicKeyPath);
        if (!resource.exists()) {
            throw new IOException("微信支付公钥文件不存在: " + wechatPayPublicKeyPath);
        }
        try (InputStream is = resource.getInputStream()) {
            String content = new String(is.readAllBytes(), StandardCharsets.UTF_8);
            log.info("成功读取微信支付公钥文件");
            return content;
        }
    }

    /**
     * 读取商户私钥文件内容
     */
    private String loadPrivateKey() throws IOException {
        Resource resource = resourceLoader.getResource(privateKeyPath);
        if (!resource.exists()) {
            throw new IOException("商户私钥文件不存在: " + privateKeyPath);
        }
        try (InputStream is = resource.getInputStream()) {
            String content = new String(is.readAllBytes(), StandardCharsets.UTF_8);
            log.info("成功读取商户私钥文件");
            return content;
        }
    }
    
    /**
     * 微信支付HTTP客户端（用于支付分等SDK未封装的API调用）
     * 自动处理请求签名和响应验签
     */
    @Bean
    public com.wechat.pay.java.core.http.HttpClient wxPayHttpClient(Config wxPaySdkConfig) {
        if (wxPaySdkConfig == null) {
            log.warn("wxPaySdkConfig 未初始化，HttpClient 跳过创建");
            return null;
        }
        return new com.wechat.pay.java.core.http.DefaultHttpClientBuilder()
                .config(wxPaySdkConfig)
                .build();
    }

    
    @PostConstruct
    public void logConfig() {
        log.info("微信支付配置加载完成 - AppID: {}, 商户号: {}, 回调地址: {}", appId, mchId, notifyUrl);
    }
}
