package com.gxwebsoft.common.core.service;

import com.gxwebsoft.common.core.config.CertificateProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 证书健康检查服务
 * 提供证书状态检查和健康监控功能
 *
 * @author 科技小王子
 * @since 2024-07-26
 */
@Slf4j
@Service
public class CertificateHealthService {

    private final CertificateService certificateService;
    private final CertificateProperties certificateProperties;

    public CertificateHealthService(CertificateService certificateService,
                                  CertificateProperties certificateProperties) {
        this.certificateService = certificateService;
        this.certificateProperties = certificateProperties;
    }

    /**
     * 自定义健康检查结果类
     */
    public static class HealthResult {
        private final String status;
        private final Map<String, Object> details;

        public HealthResult(String status, Map<String, Object> details) {
            this.status = status;
            this.details = details;
        }

        public String getStatus() {
            return status;
        }

        public Map<String, Object> getDetails() {
            return details;
        }

        public static HealthResult up(Map<String, Object> details) {
            return new HealthResult("UP", details);
        }

        public static HealthResult down(Map<String, Object> details) {
            return new HealthResult("DOWN", details);
        }
    }

    public HealthResult health() {
        try {
            Map<String, Object> details = new HashMap<>();
            boolean allHealthy = true;

            // 检查微信支付证书
            Map<String, Object> wechatHealth = checkWechatPayCertificates();
            details.put("wechatPay", wechatHealth);
            if (!(Boolean) wechatHealth.get("healthy")) {
                allHealthy = false;
            }

            // 检查支付宝证书
            Map<String, Object> alipayHealth = checkAlipayCertificates();
            details.put("alipay", alipayHealth);
            if (!(Boolean) alipayHealth.get("healthy")) {
                allHealthy = false;
            }

            // 添加系统信息
            details.put("loadMode", certificateProperties.getLoadMode());
            details.put("certRootPath", certificateProperties.getCertRootPath());

            if (allHealthy) {
                return HealthResult.up(details);
            } else {
                return HealthResult.down(details);
            }

        } catch (Exception e) {
            log.error("证书健康检查失败", e);
            Map<String, Object> errorDetails = new HashMap<>();
            errorDetails.put("error", e.getMessage());
            return HealthResult.down(errorDetails);
        }
    }

    /**
     * 检查微信支付证书健康状态
     */
    private Map<String, Object> checkWechatPayCertificates() {
        Map<String, Object> health = new HashMap<>();
        boolean healthy = true;
        Map<String, Object> certificates = new HashMap<>();

        CertificateProperties.WechatPayConfig wechatConfig = certificateProperties.getWechatPay();

        // 检查私钥证书
        String privateKeyFile = wechatConfig.getDev().getPrivateKeyFile();
        boolean privateKeyExists = certificateService.certificateExists("wechat", privateKeyFile);
        certificates.put("privateKey", Map.of(
                "file", privateKeyFile,
                "exists", privateKeyExists,
                "path", certificateService.getWechatPayCertPath(privateKeyFile)
        ));
        if (!privateKeyExists) healthy = false;

        // 检查商户证书
        String apiclientCertFile = wechatConfig.getDev().getApiclientCertFile();
        boolean apiclientCertExists = certificateService.certificateExists("wechat", apiclientCertFile);
        certificates.put("apiclientCert", Map.of(
                "file", apiclientCertFile,
                "exists", apiclientCertExists,
                "path", certificateService.getWechatPayCertPath(apiclientCertFile)
        ));
        if (!apiclientCertExists) healthy = false;

        // 检查微信支付平台证书
        String wechatpayCertFile = wechatConfig.getDev().getWechatpayCertFile();
        boolean wechatpayCertExists = certificateService.certificateExists("wechat", wechatpayCertFile);
        certificates.put("wechatpayCert", Map.of(
                "file", wechatpayCertFile,
                "exists", wechatpayCertExists,
                "path", certificateService.getWechatPayCertPath(wechatpayCertFile)
        ));
        if (!wechatpayCertExists) healthy = false;

        health.put("healthy", healthy);
        health.put("certificates", certificates);
        return health;
    }

    /**
     * 检查支付宝证书健康状态
     */
    private Map<String, Object> checkAlipayCertificates() {
        Map<String, Object> health = new HashMap<>();
        boolean healthy = true;
        Map<String, Object> certificates = new HashMap<>();

        CertificateProperties.AlipayConfig alipayConfig = certificateProperties.getAlipay();

        // 检查应用私钥
        String appPrivateKeyFile = alipayConfig.getAppPrivateKeyFile();
        boolean appPrivateKeyExists = certificateService.certificateExists("alipay", appPrivateKeyFile);
        certificates.put("appPrivateKey", Map.of(
                "file", appPrivateKeyFile,
                "exists", appPrivateKeyExists,
                "path", certificateService.getAlipayCertPath(appPrivateKeyFile)
        ));
        if (!appPrivateKeyExists) healthy = false;

        // 检查应用公钥证书
        String appCertPublicKeyFile = alipayConfig.getAppCertPublicKeyFile();
        boolean appCertExists = certificateService.certificateExists("alipay", appCertPublicKeyFile);
        certificates.put("appCertPublicKey", Map.of(
                "file", appCertPublicKeyFile,
                "exists", appCertExists,
                "path", certificateService.getAlipayCertPath(appCertPublicKeyFile)
        ));
        if (!appCertExists) healthy = false;

        // 检查支付宝公钥证书
        String alipayCertPublicKeyFile = alipayConfig.getAlipayCertPublicKeyFile();
        boolean alipayCertExists = certificateService.certificateExists("alipay", alipayCertPublicKeyFile);
        certificates.put("alipayCertPublicKey", Map.of(
                "file", alipayCertPublicKeyFile,
                "exists", alipayCertExists,
                "path", certificateService.getAlipayCertPath(alipayCertPublicKeyFile)
        ));
        if (!alipayCertExists) healthy = false;

        // 检查支付宝根证书
        String alipayRootCertFile = alipayConfig.getAlipayRootCertFile();
        boolean rootCertExists = certificateService.certificateExists("alipay", alipayRootCertFile);
        certificates.put("alipayRootCert", Map.of(
                "file", alipayRootCertFile,
                "exists", rootCertExists,
                "path", certificateService.getAlipayCertPath(alipayRootCertFile)
        ));
        if (!rootCertExists) healthy = false;

        health.put("healthy", healthy);
        health.put("certificates", certificates);
        return health;
    }

    /**
     * 获取详细的证书诊断信息
     */
    public Map<String, Object> getDiagnosticInfo() {
        Map<String, Object> diagnostic = new HashMap<>();

        try {
            // 基本系统信息
            diagnostic.put("loadMode", certificateProperties.getLoadMode());
            diagnostic.put("certRootPath", certificateProperties.getCertRootPath());
            diagnostic.put("devCertPath", certificateProperties.getDevCertPath());

            // 获取所有证书状态
            diagnostic.put("certificateStatus", certificateService.getAllCertificateStatus());

            // 健康检查结果
            HealthResult health = health();
            diagnostic.put("healthStatus", health.getStatus());
            diagnostic.put("healthDetails", health.getDetails());

        } catch (Exception e) {
            log.error("获取证书诊断信息失败", e);
            diagnostic.put("error", e.getMessage());
        }

        return diagnostic;
    }

    /**
     * 检查特定证书的详细信息
     */
    public Map<String, Object> checkSpecificCertificate(String certType, String fileName) {
        Map<String, Object> result = new HashMap<>();

        try {
            boolean exists = certificateService.certificateExists(certType, fileName);
            String path = certificateService.getCertificateFilePath(certType, fileName);

            result.put("certType", certType);
            result.put("fileName", fileName);
            result.put("exists", exists);
            result.put("path", path);

            if (exists && (fileName.endsWith(".crt") || fileName.endsWith(".pem"))) {
                // 尝试验证证书
                CertificateService.CertificateInfo certInfo =
                    certificateService.validateX509Certificate(certType, fileName);
                result.put("certificateInfo", certInfo);
            }

        } catch (Exception e) {
            log.error("检查证书失败: {}/{}", certType, fileName, e);
            result.put("error", e.getMessage());
        }

        return result;
    }
}
