package com.jeesharp.business.modules.pay.paywechatconfig.service.impl;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.pay.paychannelconfig.entity.PayChannelConfig;
import com.jeesharp.business.modules.pay.paychannelconfig.enums.PayChannelCodeEnum;
import com.jeesharp.business.modules.pay.paychannelconfig.service.PayChannelConfigService;
import com.jeesharp.business.modules.pay.paychannelconfig.support.PayChannelConfigMergeSupport;
import com.jeesharp.business.modules.pay.paychannelconfig.support.PayChannelTenantSupport;
import com.jeesharp.business.modules.pay.paywechatconfig.entity.PayWechatConfig;
import com.jeesharp.business.modules.pay.paywechatconfig.enums.PayWechatConfigStatusEnum;
import com.jeesharp.business.modules.pay.paywechatconfig.mapper.PayWechatConfigMapper;
import com.jeesharp.business.modules.pay.paywechatconfig.service.PayWechatConfigService;
import com.jeesharp.business.modules.pay.paywechatconfig.vo.PayWechatConfigQueryVO;
import com.jeesharp.framework.mybatis.core.service.CrudService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 微信支付配置领域服务实现。
 *
 * @author jeesharp
 * @since 2026-05-25
 */
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class PayWechatConfigServiceImpl extends CrudService<PayWechatConfigMapper, PayWechatConfig, PayWechatConfigQueryVO>
        implements PayWechatConfigService {

    private final PayChannelConfigService payChannelConfigService;

    /**
     * 按主键区分更新与新增：父类 {@link CrudService#save} 对本配置可能始终执行 insert，导致重复行或无法更新。
     * <p>与 {@code PayWechatConfigApplicationService} 在保存前补全 {@code id}、合并敏感字段配合使用。</p>
     *
     * @author jeesharp
     * @since 2026-05-26
     */
    @Override
    @Transactional(readOnly = false)
    public boolean save(PayWechatConfig entity) {
        if (entity == null) {
            return false;
        }
        if (StrUtil.isNotBlank(entity.getId())) {
            PayWechatConfig persisted = get(entity.getId());
            if (persisted != null) {
                entity.preUpdate();
                return getBaseMapper().updateById(entity) > 0;
            }
        }
        entity.preInsert();
        return getBaseMapper().insert(entity) > 0;
    }

    @Override
    @Transactional(readOnly = false)
    public boolean delete(String id) {
        PayWechatConfig row = get(id);
        PayChannelTenantSupport.assertDeletableTenantCode(row != null ? row.getTenantCode() : null);
        return super.delete(id);
    }

    @Override
    @Transactional(readOnly = false)
    public boolean batchDelete(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return true;
        }
        for (String id : ids) {
            PayWechatConfig row = get(id);
            PayChannelTenantSupport.assertDeletableTenantCode(row != null ? row.getTenantCode() : null);
        }
        return super.batchDelete(ids);
    }

    @Override
    public PayWechatConfig findActive(String tenantId) {
        String tid = PayChannelTenantSupport.normalize(tenantId);
        PayChannelConfig channel = payChannelConfigService.findActiveByChannelCode(
                PayChannelCodeEnum.WECHAT.getCode(), tid);
        PayWechatConfig wechat = null;
        if (channel != null && StrUtil.isNotBlank(channel.getId())) {
            wechat = getBaseMapper().findByChannelConfigId(channel.getId());
        }
        if (wechat == null) {
            if (tid != null) {
                wechat = getBaseMapper().findActiveByTenantId(tid);
            }
            if (wechat == null) {
                wechat = getBaseMapper().findActivePlatform();
            }
            if (wechat == null) {
                wechat = getBaseMapper().findActive();
            }
            if (channel == null) {
                channel = payChannelConfigService.findActiveByChannelCode(
                        PayChannelCodeEnum.WECHAT.getCode(), tid);
            }
        }
        return PayChannelConfigMergeSupport.mergeWechatNotify(wechat, channel);
    }

    @Override
    public PayWechatConfig findByConfigCode(String configCode, String tenantId) {
        if (StrUtil.isBlank(configCode)) {
            return null;
        }
        String tid = PayChannelTenantSupport.normalize(tenantId);
        PayWechatConfig row = null;
        if (tid != null) {
            row = getBaseMapper().findByConfigCodeAndTenant(configCode.trim(), tid);
        }
        if (row == null) {
            row = getBaseMapper().findByConfigCode(configCode.trim());
        }
        return row;
    }

    @Override
    public PayWechatConfig findByChannelConfigId(String channelConfigId) {
        if (StrUtil.isBlank(channelConfigId)) {
            return null;
        }
        return getBaseMapper().findByChannelConfigId(channelConfigId.trim());
    }

    @Override
    @Transactional(readOnly = false)
    public void disableOtherActiveExcept(String tenantId, String keepId) {
        getBaseMapper().disableOtherActiveExcept(
                PayChannelTenantSupport.normalize(tenantId),
                keepId,
                PayWechatConfigStatusEnum.ENABLED.getValue(),
                PayWechatConfigStatusEnum.DISABLED.getValue());
    }
}
