package com.gxwebsoft.common.core.utils;

import com.gxwebsoft.common.core.config.CertificateProperties;
import com.gxwebsoft.common.core.service.PaymentCacheService;
import com.gxwebsoft.common.system.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 微信支付配置检查器
 * 用于快速检查和验证微信支付配置状态
 * 
 * @author 科技小王子
 * @since 2025-07-29
 */
@Slf4j
@Component
public class WechatPayConfigChecker {

    @Autowired
    private PaymentCacheService paymentCacheService;
    
    @Autowired
    private CertificateLoader certificateLoader;
    
    @Autowired
    private CertificateProperties certConfig;
    
    @Value("${spring.profiles.active:dev}")
    private String activeProfile;

    /**
     * 检查租户的微信支付配置状态
     * 
     * @param tenantId 租户ID
     * @return 配置状态报告
     */
    public ConfigStatus checkTenantConfig(Integer tenantId) {
        ConfigStatus status = new ConfigStatus();
        status.tenantId = tenantId;
        status.environment = activeProfile;
        
        try {
            // 获取支付配置
            Payment payment = paymentCacheService.getWechatPayConfig(tenantId);
            if (payment == null) {
                status.hasError = true;
                status.errorMessage = "支付配置不存在";
                return status;
            }
            
            status.merchantId = payment.getMchId();
            status.appId = payment.getAppId();
            status.serialNumber = payment.getMerchantSerialNumber();
            status.hasApiKey = payment.getApiKey() != null && !payment.getApiKey().isEmpty();
            status.apiKeyLength = payment.getApiKey() != null ? payment.getApiKey().length() : 0;
            
            // 检查公钥配置
            if (payment.getPubKey() != null && !payment.getPubKey().isEmpty() && 
                payment.getPubKeyId() != null && !payment.getPubKeyId().isEmpty()) {
                
                status.hasPublicKey = true;
                status.publicKeyFile = payment.getPubKey();
                status.publicKeyId = payment.getPubKeyId();
                status.configMode = "公钥模式";
                
                // 检查公钥文件是否存在
                String tenantCertPath = "dev/wechat/" + tenantId;
                String pubKeyPath = tenantCertPath + "/" + payment.getPubKey();
                status.publicKeyExists = certificateLoader.certificateExists(pubKeyPath);
                
            } else {
                status.hasPublicKey = false;
                status.configMode = "自动证书模式";
            }
            
            // 检查私钥文件
            String tenantCertPath = "dev/wechat/" + tenantId;
            String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile();
            status.privateKeyExists = certificateLoader.certificateExists(privateKeyPath);
            
            // 检查商户证书文件
            String apiclientCertPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getApiclientCertFile();
            status.merchantCertExists = certificateLoader.certificateExists(apiclientCertPath);
            
            // 评估配置完整性
            evaluateConfigCompleteness(status);
            
        } catch (Exception e) {
            status.hasError = true;
            status.errorMessage = "检查配置时发生异常: " + e.getMessage();
            log.error("检查租户 {} 配置时发生异常", tenantId, e);
        }
        
        return status;
    }

    /**
     * 评估配置完整性
     */
    private void evaluateConfigCompleteness(ConfigStatus status) {
        if (status.hasError) {
            return;
        }
        
        // 基本配置检查
        if (status.merchantId == null || status.merchantId.isEmpty()) {
            status.addIssue("商户号未配置");
        }
        
        if (status.appId == null || status.appId.isEmpty()) {
            status.addIssue("应用ID未配置");
        }
        
        if (status.serialNumber == null || status.serialNumber.isEmpty()) {
            status.addIssue("商户证书序列号未配置");
        }
        
        if (!status.hasApiKey) {
            status.addIssue("APIv3密钥未配置");
        } else if (status.apiKeyLength != 32) {
            status.addIssue("APIv3密钥长度错误，应为32位，实际为" + status.apiKeyLength + "位");
        }
        
        if (!status.privateKeyExists) {
            status.addIssue("私钥文件不存在");
        }
        
        // 公钥模式特定检查
        if (status.hasPublicKey) {
            if (!status.publicKeyExists) {
                status.addIssue("公钥文件不存在");
            }
        }
        
        // 设置配置状态
        if (status.issues.isEmpty()) {
            status.configComplete = true;
            status.recommendation = "✅ 配置完整，建议使用当前配置";
        } else {
            status.configComplete = false;
            if (status.hasPublicKey) {
                status.recommendation = "⚠️ 公钥配置不完整，建议修复问题或回退到自动证书模式";
            } else {
                status.recommendation = "⚠️ 自动证书配置不完整，建议配置公钥模式或修复当前问题";
            }
        }
    }

    /**
     * 生成配置建议
     */
    public String generateConfigAdvice(Integer tenantId) {
        ConfigStatus status = checkTenantConfig(tenantId);
        
        StringBuilder advice = new StringBuilder();
        advice.append("=== 租户 ").append(tenantId).append(" 微信支付配置建议 ===\n\n");
        
        advice.append("当前配置模式: ").append(status.configMode).append("\n");
        advice.append("配置完整性: ").append(status.configComplete ? "完整" : "不完整").append("\n\n");
        
        if (status.hasError) {
            advice.append("❌ 错误: ").append(status.errorMessage).append("\n\n");
            return advice.toString();
        }
        
        // 基本信息
        advice.append("📋 基本信息:\n");
        advice.append("  商户号: ").append(status.merchantId).append("\n");
        advice.append("  应用ID: ").append(status.appId).append("\n");
        advice.append("  序列号: ").append(status.serialNumber).append("\n");
        advice.append("  API密钥: ").append(status.hasApiKey ? "已配置(" + status.apiKeyLength + "位)" : "未配置").append("\n\n");
        
        // 证书文件状态
        advice.append("📁 证书文件状态:\n");
        advice.append("  私钥文件: ").append(status.privateKeyExists ? "✅ 存在" : "❌ 不存在").append("\n");
        advice.append("  商户证书: ").append(status.merchantCertExists ? "✅ 存在" : "⚠️ 不存在").append("\n");
        
        if (status.hasPublicKey) {
            advice.append("  公钥文件: ").append(status.publicKeyExists ? "✅ 存在" : "❌ 不存在").append("\n");
            advice.append("  公钥ID: ").append(status.publicKeyId).append("\n");
        }
        advice.append("\n");
        
        // 问题列表
        if (!status.issues.isEmpty()) {
            advice.append("⚠️ 发现的问题:\n");
            for (String issue : status.issues) {
                advice.append("  - ").append(issue).append("\n");
            }
            advice.append("\n");
        }
        
        // 建议
        advice.append("💡 建议:\n");
        advice.append("  ").append(status.recommendation).append("\n\n");
        
        if (!status.hasPublicKey) {
            advice.append("🔧 配置公钥模式的步骤:\n");
            advice.append("  1. 获取微信支付平台公钥文件和公钥ID\n");
            advice.append("  2. 将公钥文件放置到: src/main/resources/dev/wechat/").append(tenantId).append("/\n");
            advice.append("  3. 执行SQL更新数据库配置:\n");
            advice.append("     UPDATE sys_payment SET \n");
            advice.append("       pub_key = 'wechatpay_public_key.pem',\n");
            advice.append("       pub_key_id = 'YOUR_PUBLIC_KEY_ID'\n");
            advice.append("     WHERE tenant_id = ").append(tenantId).append(" AND type = 0;\n\n");
        }
        
        advice.append("=== 配置建议结束 ===");
        return advice.toString();
    }

    /**
     * 配置状态类
     */
    public static class ConfigStatus {
        public Integer tenantId;
        public String environment;
        public String merchantId;
        public String appId;
        public String serialNumber;
        public boolean hasApiKey;
        public int apiKeyLength;
        public boolean hasPublicKey;
        public String publicKeyFile;
        public String publicKeyId;
        public boolean publicKeyExists;
        public boolean privateKeyExists;
        public boolean merchantCertExists;
        public String configMode;
        public boolean configComplete;
        public boolean hasError;
        public String errorMessage;
        public String recommendation;
        public java.util.List<String> issues = new java.util.ArrayList<>();
        
        public void addIssue(String issue) {
            issues.add(issue);
        }
    }
}
