package com.jeesharp.business.modules.finance.merchantsettle.application;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.finance.merchantsettle.convert.MerchantSettleConfigConvert;
import com.jeesharp.business.modules.finance.merchantsettle.dto.MerchantSettleConfigSaveDTO;
import com.jeesharp.business.modules.finance.merchantsettle.entity.MerchantSettleConfig;
import com.jeesharp.business.modules.finance.merchantsettle.enums.MerchantSettleConfigStatusEnum;
import com.jeesharp.business.modules.finance.merchantsettle.enums.SettleModeEnum;
import com.jeesharp.business.modules.finance.merchantsettle.service.MerchantSettleConfigService;
import com.jeesharp.business.modules.finance.merchantsettle.vo.MerchantSettleConfigInfoVO;
import com.jeesharp.business.modules.finance.merchantsettle.vo.MerchantSettleConfigListVO;
import com.jeesharp.business.modules.finance.merchantsettle.vo.MerchantSettleConfigQueryVO;
import com.jeesharp.business.modules.finance.merchantsettle.vo.MerchantSettleConfigSnapshotVO;
import com.jeesharp.business.modules.finance.merchantsettle.vo.PaySettleResolveVO;
import com.jeesharp.framework.exception.BizErrorException;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.pojo.query.PageRespVO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

/**
 * 商户结算配置应用服务：编排查询、新增、更新及跨模块快照解析。
 *
 * @author jeesharp
 * @since 2026-06-11
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class MerchantSettleConfigApplicationService {

    private final MerchantSettleConfigService merchantSettleConfigService;

    public MerchantSettleConfigInfoVO get(String id) {
        return MerchantSettleConfigConvert.INSTANCE.toInfoVO(merchantSettleConfigService.get(id));
    }

    public PageRespVO<MerchantSettleConfigListVO> findPage(Page<MerchantSettleConfig> page,
            MerchantSettleConfigQueryVO query) {
        Page<MerchantSettleConfig> result = merchantSettleConfigService.findPage(page, query);
        return MerchantSettleConfigConvert.INSTANCE.toPageRespVO(result);
    }

    @Transactional(readOnly = false)
    public void create(MerchantSettleConfigSaveDTO dto) {
        if (StrUtil.isNotBlank(dto.getId())) {
            throw new BizErrorException("新增请求不应携带主键 id");
        }
        merchantSettleConfigService.createConfig(MerchantSettleConfigConvert.INSTANCE.toEntity(dto));
    }

    @Transactional(readOnly = false)
    public void update(MerchantSettleConfigSaveDTO dto) {
        if (StrUtil.isBlank(dto.getId())) {
            throw new BizErrorException("更新请求必须携带主键 id");
        }
        merchantSettleConfigService.updateConfig(MerchantSettleConfigConvert.INSTANCE.toEntity(dto));
    }

    @Transactional(readOnly = false)
    public void delete(String ids) {
        merchantSettleConfigService.batchDelete(Arrays.asList(ids.split(",")));
    }

    /**
     * 按商户租户解析结算快照；无配置时返回平台代收默认值。
     */
    public MerchantSettleConfigSnapshotVO resolveSnapshot(String merchantTenantId) {
        MerchantSettleConfigSnapshotVO snapshot = new MerchantSettleConfigSnapshotVO();
        snapshot.setMerchantTenantId(merchantTenantId);
        snapshot.setSettleMode(SettleModeEnum.PLATFORM_COLLECT.getValue());
        snapshot.setCommissionRate(BigDecimal.ZERO);
        snapshot.setEnabled(true);
        snapshot.setNeedProfitSharing(false);

        MerchantSettleConfig config = merchantSettleConfigService.getByMerchantTenantId(merchantTenantId);
        if (config == null) {
            return snapshot;
        }
        snapshot.setSettleMode(config.getSettleMode());
        snapshot.setCommissionRate(config.getCommissionRate() != null ? config.getCommissionRate() : BigDecimal.ZERO);
        snapshot.setSubMchId(config.getSubMchId());
        boolean enabled = MerchantSettleConfigStatusEnum.ENABLED.getValue().equals(config.getStatus());
        snapshot.setEnabled(enabled);
        snapshot.setNeedProfitSharing(enabled
                && SettleModeEnum.WECHAT_PROFIT_SHARING.getValue().equals(config.getSettleMode()));
        return snapshot;
    }

    /**
     * 批量租户中是否存在需微信分账标记的商户（合并支付场景）。
     */
    public boolean anyNeedProfitSharing(List<String> merchantTenantIds) {
        return Boolean.TRUE.equals(resolvePaySettle(merchantTenantIds).getNeedProfitSharing());
    }

    /**
     * 解析整笔支付结算模式：默认平台代收；涉及商户中任一启用微信分账则标记分账。
     */
    public PaySettleResolveVO resolvePaySettle(List<String> merchantTenantIds) {
        PaySettleResolveVO result = new PaySettleResolveVO();
        result.setSettleMode(SettleModeEnum.PLATFORM_COLLECT.getValue());
        result.setNeedProfitSharing(false);
        if (merchantTenantIds == null || merchantTenantIds.isEmpty()) {
            return result;
        }
        boolean need = merchantTenantIds.stream()
                .filter(StrUtil::isNotBlank)
                .distinct()
                .map(this::resolveSnapshot)
                .anyMatch(vo -> Boolean.TRUE.equals(vo.getNeedProfitSharing()));
        result.setNeedProfitSharing(need);
        if (need) {
            result.setSettleMode(SettleModeEnum.WECHAT_PROFIT_SHARING.getValue());
        }
        return result;
    }
}
