package com.jeesharp.business.modules.mall.application;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.mall.application.support.MallFirstOrderPromoSupport;
import com.jeesharp.business.modules.mall.convert.MallFirstOrderConfigConvert;
import com.jeesharp.business.modules.mall.dto.MallFirstOrderConfigSaveDTO;
import com.jeesharp.business.modules.mall.entity.MallFirstOrderConfig;
import com.jeesharp.business.modules.mall.enums.MallFirstOrderConfigStatusEnum;
import com.jeesharp.business.modules.mall.service.MallFirstOrderConfigService;
import com.jeesharp.business.modules.mall.vo.MallFirstOrderCheckVO;
import com.jeesharp.business.modules.mall.vo.MallFirstOrderConfigInfoVO;
import com.jeesharp.business.modules.mall.vo.MallFirstOrderConfigListVO;
import com.jeesharp.business.modules.mall.vo.MallFirstOrderConfigQueryVO;
import com.jeesharp.framework.exception.BizErrorException;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.pojo.query.PageRespVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

/**
 * 首单优惠应用服务：配置维护、首单资格判断、下单立减与支付后赠券编排。
 *
 * @author jeesharp
 * @since 2026-02-05
 */
@Slf4j
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class MallFirstOrderConfigApplicationService {

    private final MallFirstOrderConfigService mallFirstOrderConfigService;
    private final MallFirstOrderPromoSupport mallFirstOrderPromoSupport;

    public MallFirstOrderConfigInfoVO get(String id) {
        return MallFirstOrderConfigConvert.INSTANCE.toInfoVO(mallFirstOrderConfigService.get(id));
    }

    public PageRespVO<MallFirstOrderConfigListVO> findPage(Page<MallFirstOrderConfig> page, MallFirstOrderConfigQueryVO query) {
        Page<MallFirstOrderConfig> result = mallFirstOrderConfigService.findPage(page, query);
        return MallFirstOrderConfigConvert.INSTANCE.toPageRespVO(result);
    }

    @Transactional(readOnly = false)
    public void save(MallFirstOrderConfigSaveDTO dto) {
        validateSave(dto);
        MallFirstOrderConfig entity = MallFirstOrderConfigConvert.INSTANCE.toEntity(dto);
        if (StrUtil.isBlank(dto.getId())) {
            mallFirstOrderConfigService.createConfig(entity);
            return;
        }
        mallFirstOrderConfigService.updateConfig(entity);
    }

    @Transactional(readOnly = false)
    public void delete(String ids) {
        mallFirstOrderConfigService.batchDelete(StrUtil.splitTrim(ids, ','));
    }

    public MallFirstOrderConfig getEnabledConfig() {
        return mallFirstOrderConfigService.getEnabledConfig();
    }

    public boolean checkIsFirstOrder(String memberId) {
        return mallFirstOrderConfigService.checkIsFirstOrder(memberId);
    }

    /**
     * 移动端：是否首单及当前启用配置摘要。
     */
    public MallFirstOrderCheckVO buildCheckResult(String memberId) {
        MallFirstOrderCheckVO vo = new MallFirstOrderCheckVO();
        boolean firstOrder = checkIsFirstOrder(memberId);
        vo.setFirstOrder(firstOrder);
        if (!firstOrder) {
            return vo;
        }
        MallFirstOrderConfig config = getEnabledConfig();
        if (config == null) {
            return vo;
        }
        vo.setDiscountAmount(config.getDiscountAmount());
        vo.setCouponTemplateIds(config.getCouponTemplateIds());
        return vo;
    }

    /**
     * 结算/下单：解析首单立减金额（不超过订单应付）。
     */
    public BigDecimal resolveFirstOrderDiscount(String memberId, BigDecimal payableBeforeDiscount) {
        return mallFirstOrderPromoSupport.resolveFirstOrderDiscount(memberId, payableBeforeDiscount);
    }

    /**
     * 支付成功后：首单会员按配置发放优惠券（失败仅记日志，不影响支付结果）。
     */
    @Transactional(readOnly = false)
    public void tryGrantCouponsAfterFirstPaidOrder(String memberId) {
        mallFirstOrderPromoSupport.tryGrantCouponsAfterFirstPaidOrder(memberId);
    }

    private void validateSave(MallFirstOrderConfigSaveDTO dto) {
        boolean hasDiscount = dto.getDiscountAmount() != null
                && dto.getDiscountAmount().compareTo(BigDecimal.ZERO) > 0;
        boolean hasCoupon = StrUtil.isNotBlank(dto.getCouponTemplateIds());
        if (!hasDiscount && !hasCoupon) {
            throw new BizErrorException("请至少配置首单立减金额或赠送优惠券模板");
        }
        if (MallFirstOrderConfigStatusEnum.ENABLED.getValue().equals(dto.getStatus())) {
            MallFirstOrderConfig enabled = getEnabledConfig();
            if (enabled != null && (StrUtil.isBlank(dto.getId()) || !enabled.getId().equals(dto.getId()))) {
                throw new BizErrorException("已存在启用中的首单优惠配置，请先禁用后再启用本条");
            }
        }
    }

}
