package com.gxwebsoft.common.core.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.config.CertificateProperties;
import com.gxwebsoft.common.core.service.CertificateService;
import com.gxwebsoft.common.core.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 支付宝工具类
 * 支持新的证书管理系统
 * @author leng
 *
 */
@Slf4j
@Component
public class AlipayConfigUtil {
  private final StringRedisTemplate stringRedisTemplate;
  public Integer tenantId;
  public String gateway;
  public JSONObject config;
  public String appId;
  public String privateKey;
  public String appCertPublicKey;
  public String alipayCertPublicKey;
  public String alipayRootCert;

  @Value("${spring.profiles.active}")
  private String active;

  @Resource
  private ConfigProperties pathConfig;
  @Resource
  private CertificateService certificateService;
  @Resource
  private CertificateProperties certificateProperties;

  public AlipayConfigUtil(StringRedisTemplate stringRedisTemplate){
    this.stringRedisTemplate = stringRedisTemplate;
  }

  // 实例化客户端
  public DefaultAlipayClient alipayClient(Integer tenantId) throws AlipayApiException {
    this.gateway = "https://openapi.alipay.com/gateway.do";
    this.tenantId = tenantId;
    this.payment(tenantId);
    CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
    certAlipayRequest.setServerUrl(this.gateway);
    certAlipayRequest.setAppId(this.appId);
    certAlipayRequest.setPrivateKey(this.privateKey);
    certAlipayRequest.setFormat(AlipayConstants.FORMAT_JSON);
    certAlipayRequest.setCharset(AlipayConstants.CHARSET_UTF8);
    certAlipayRequest.setSignType(AlipayConstants.SIGN_TYPE_RSA2);
    certAlipayRequest.setCertPath(this.appCertPublicKey);
    certAlipayRequest.setAlipayPublicCertPath(this.alipayCertPublicKey);
    certAlipayRequest.setRootCertPath(this.alipayRootCert);
//    System.out.println("this.appId = " + this.appId);
//    System.out.println("this.appId = " + this.gateway);
//    System.out.println("this.appId = " + this.privateKey);
//    System.out.println("this.appId = " + this.appCertPublicKey);
//    System.out.println("this.appId = " + this.alipayCertPublicKey);
//    System.out.println("this.appId = " + this.alipayRootCert);
//    System.out.println("this.config = " + this.config);
    return new DefaultAlipayClient(certAlipayRequest);
  }

  /**
   * 获取支付宝秘钥
   */
  public JSONObject payment(Integer tenantId) {
    log.debug("获取支付宝配置，租户ID: {}", tenantId);
    String key = "cache".concat(tenantId.toString()).concat(":setting:payment");
    log.debug("Redis缓存key: {}", key);

    // 测试期间注释掉从缓存获取支付配置
    // String cache = stringRedisTemplate.opsForValue().get(key);
    // if (cache == null) {
    //   throw new BusinessException("支付方式未配置");
    // }

    // 测试期间：模拟缓存为空的情况
    String cache = null;
    log.debug("测试模式：支付宝配置缓存设为null");
    if (cache == null) {
      throw new BusinessException("支付方式未配置（测试模式：缓存已注释）");
    }

    // 解析json数据
    JSONObject payment = JSON.parseObject(cache.getBytes());
    this.config = payment;
    this.appId = payment.getString("alipayAppId");
    this.privateKey = payment.getString("privateKey");

    try {
      if (active.equals("dev")) {
        // 开发环境：使用证书服务获取证书路径
        CertificateProperties.AlipayConfig alipayConfig = certificateProperties.getAlipay();
        this.appCertPublicKey = certificateService.getAlipayCertPath(alipayConfig.getAppCertPublicKeyFile());
        this.alipayCertPublicKey = certificateService.getAlipayCertPath(alipayConfig.getAlipayCertPublicKeyFile());
        this.alipayRootCert = certificateService.getAlipayCertPath(alipayConfig.getAlipayRootCertFile());

        log.info("开发环境支付宝证书路径:");
        log.info("应用证书相对路径: {}", this.appCertPublicKey);
        log.info("支付宝证书相对路径: {}", this.alipayCertPublicKey);
        log.info("根证书相对路径: {}", this.alipayRootCert);

        // 打印完整的绝对路径
        try {
          if (certificateProperties.isClasspathMode()) {
            log.info("支付宝证书加载模式: CLASSPATH");
            org.springframework.core.io.ClassPathResource appCertResource = new org.springframework.core.io.ClassPathResource(this.appCertPublicKey);
            org.springframework.core.io.ClassPathResource alipayCertResource = new org.springframework.core.io.ClassPathResource(this.alipayCertPublicKey);
            org.springframework.core.io.ClassPathResource rootCertResource = new org.springframework.core.io.ClassPathResource(this.alipayRootCert);

            if (appCertResource.exists()) {
              log.info("应用证书完整绝对路径: {}", appCertResource.getFile().getAbsolutePath());
            }
            if (alipayCertResource.exists()) {
              log.info("支付宝证书完整绝对路径: {}", alipayCertResource.getFile().getAbsolutePath());
            }
            if (rootCertResource.exists()) {
              log.info("根证书完整绝对路径: {}", rootCertResource.getFile().getAbsolutePath());
            }
          } else {
            log.info("支付宝证书加载模式: FILESYSTEM");
            log.info("应用证书完整绝对路径: {}", new java.io.File(this.appCertPublicKey).getAbsolutePath());
            log.info("支付宝证书完整绝对路径: {}", new java.io.File(this.alipayCertPublicKey).getAbsolutePath());
            log.info("根证书完整绝对路径: {}", new java.io.File(this.alipayRootCert).getAbsolutePath());
          }
        } catch (Exception e) {
          log.warn("获取支付宝证书绝对路径失败: {}", e.getMessage());
        }

        // 检查证书文件是否存在
        if (!certificateService.certificateExists("alipay", alipayConfig.getAppCertPublicKeyFile())) {
          throw new RuntimeException("支付宝应用证书文件不存在");
        }
        if (!certificateService.certificateExists("alipay", alipayConfig.getAlipayCertPublicKeyFile())) {
          throw new RuntimeException("支付宝公钥证书文件不存在");
        }
        if (!certificateService.certificateExists("alipay", alipayConfig.getAlipayRootCertFile())) {
          throw new RuntimeException("支付宝根证书文件不存在");
        }
      } else {
        // 生产环境：使用上传的证书文件
        // 修改路径拼接规则：uploadPath + "file" + 数据库存储的相对路径
        String appCertPath = payment.getString("appCertPublicKey");
        String alipayCertPath = payment.getString("alipayCertPublicKey");
        String rootCertPath = payment.getString("alipayRootCert");

        this.appCertPublicKey = pathConfig.getUploadPath() + "file" + appCertPath;
        this.alipayCertPublicKey = pathConfig.getUploadPath() + "file" + alipayCertPath;
        this.alipayRootCert = pathConfig.getUploadPath() + "file" + rootCertPath;

        log.info("生产环境支付宝证书路径构建:");
        log.info("上传根路径: {}", pathConfig.getUploadPath());
        log.info("应用证书 - 数据库路径: {}, 完整路径: {}", appCertPath, this.appCertPublicKey);
        log.info("支付宝证书 - 数据库路径: {}, 完整路径: {}", alipayCertPath, this.alipayCertPublicKey);
        log.info("根证书 - 数据库路径: {}, 完整路径: {}", rootCertPath, this.alipayRootCert);
      }
    } catch (Exception e) {
      log.error("配置支付宝证书路径失败: {}", e.getMessage(), e);
      throw new RuntimeException("支付宝证书配置失败: " + e.getMessage());
    }

    return payment;
  }

  public String appId(){
    return this.appId;
  }

  public String privateKey(){
    return this.privateKey;
  }

  public String appCertPublicKey(){
    return this.appCertPublicKey;
  }

  public String alipayCertPublicKey(){
    return this.alipayCertPublicKey;
  }

  public String alipayRootCert(){
    return this.alipayRootCert;
  }




}
