package com.gxwebsoft.common.core.service;

import cn.hutool.core.util.ObjectUtil;
import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.system.entity.Payment;
import com.gxwebsoft.common.system.param.PaymentParam;
import com.gxwebsoft.common.system.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 支付配置缓存服务
 * 统一管理支付配置的缓存读取，支持 Payment:1* 格式
 *
 * @author 科技小王子
 * @since 2025-07-27
 */
@Slf4j
@Service
public class PaymentCacheService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private PaymentService paymentService;

    /**
     * 根据支付类型获取支付配置
     * 优先从 Payment:1{payType} 格式的缓存读取
     *
     * @param payType 支付类型 (0=微信支付, 1=支付宝, 2=其他)
     * @param tenantId 租户ID (用于兜底查询)
     * @return Payment 支付配置
     */
    public Payment getPaymentConfig(Integer payType, Integer tenantId) {
        // 1. 优先使用 Payment:1{payType} 格式的缓存键
        String primaryKey = "Payment:1:" + tenantId;
        Payment payment = redisUtil.get(primaryKey, Payment.class);

        if (ObjectUtil.isNotEmpty(payment)) {
            log.debug("从缓存获取支付配置成功: {}", primaryKey);
            return payment;
        }

        // 2. 如果 Payment:1* 格式不存在，尝试原有格式
        String fallbackKey = "Payment:" + payType + ":" + tenantId;
        payment = redisUtil.get(fallbackKey, Payment.class);

        if (ObjectUtil.isNotEmpty(payment)) {
            log.debug("从兜底缓存获取支付配置成功: {}", fallbackKey);
            // 将查询结果缓存到 Payment:1* 格式
            redisUtil.set(primaryKey, payment);
            return payment;
        }

        // 3. 最后从数据库查询
        log.debug("从数据库查询支付配置, payType: {}, tenantId: {}", payType, tenantId);
        PaymentParam paymentParam = new PaymentParam();
        paymentParam.setType(payType);
        paymentParam.setTenantId(tenantId); // 设置租户ID进行过滤
        List<Payment> payments = paymentService.listRel(paymentParam);

        if (payments.isEmpty()) {
            throw new BusinessException("请完成支付配置，支付类型: " + payType);
        }

        Payment dbPayment = payments.get(0);

        // 清理时间字段，避免序列化问题
        Payment cachePayment = cleanPaymentForCache(dbPayment);

        // 将查询结果缓存到 Payment:1* 格式
        redisUtil.set(primaryKey, cachePayment);
        log.debug("支付配置已缓存到: {}", primaryKey);

        return dbPayment;  // 返回原始对象，不影响业务逻辑
    }

    /**
     * 缓存支付配置
     * 同时缓存到 Payment:1{payType} 和原有格式
     *
     * @param payment 支付配置
     * @param tenantId 租户ID
     */
    public void cachePaymentConfig(Payment payment, Integer tenantId) {
        // 缓存到 Payment:1* 格式
        String primaryKey = "Payment:1" + payment.getCode();
        redisUtil.set(primaryKey, payment);
        log.debug("支付配置已缓存到: {}", primaryKey);

        // 兼容原有格式
        String legacyKey = "Payment:" + payment.getCode() + ":" + tenantId;
        redisUtil.set(legacyKey, payment);
        log.debug("支付配置已缓存到兼容格式: {}", legacyKey);
    }

    /**
     * 删除支付配置缓存
     * 同时删除 Payment:1{payType} 和原有格式
     *
     * @param paymentCode 支付代码 (可以是String或Integer)
     * @param tenantId 租户ID
     */
    public void removePaymentConfig(String paymentCode, Integer tenantId) {
        // 删除 Payment:1* 格式缓存
        String primaryKey = "Payment:1" + paymentCode;
        redisUtil.delete(primaryKey);
        log.debug("已删除支付配置缓存: {}", primaryKey);

        // 删除原有格式缓存
        String legacyKey = "Payment:" + paymentCode + ":" + tenantId;
        redisUtil.delete(legacyKey);
        log.debug("已删除兼容格式缓存: {}", legacyKey);
    }

    /**
     * 获取微信支付配置 (payType = 0)
     */
    public Payment getWechatPayConfig(Integer tenantId) {
        return getPaymentConfig(0, tenantId);
    }

    /**
     * 获取支付宝配置 (payType = 1)
     */
    public Payment getAlipayConfig(Integer tenantId) {
        return getPaymentConfig(1, tenantId);
    }

    /**
     * 清理Payment对象用于缓存
     * 移除可能导致序列化问题的时间字段
     */
    private Payment cleanPaymentForCache(Payment original) {
        if (original == null) {
            return null;
        }

        Payment cleaned = new Payment();
        // 复制所有业务相关字段
        cleaned.setId(original.getId());
        cleaned.setName(original.getName());
        cleaned.setType(original.getType());
        cleaned.setCode(original.getCode());
        cleaned.setImage(original.getImage());
        cleaned.setWechatType(original.getWechatType());
        cleaned.setAppId(original.getAppId());
        cleaned.setMchId(original.getMchId());
        cleaned.setApiKey(original.getApiKey());
        cleaned.setApiclientCert(original.getApiclientCert());
        cleaned.setApiclientKey(original.getApiclientKey());
        cleaned.setPubKey(original.getPubKey());
        cleaned.setPubKeyId(original.getPubKeyId());
        cleaned.setMerchantSerialNumber(original.getMerchantSerialNumber());
        cleaned.setNotifyUrl(original.getNotifyUrl());
        cleaned.setComments(original.getComments());
        cleaned.setSortNumber(original.getSortNumber());
        cleaned.setStatus(original.getStatus());
        cleaned.setDeleted(original.getDeleted());
        cleaned.setTenantId(original.getTenantId());

        // 不设置时间字段，避免序列化问题
        // cleaned.setCreateTime(null);
        // cleaned.setUpdateTime(null);

        return cleaned;
    }
}
