package co.yixiang.yshop.module.member.service.integralrule.strategy;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.spring.SpringUtil;
import co.yixiang.yshop.module.member.api.integralRule.IntegralRuleDTO;
import co.yixiang.yshop.module.member.dal.dataobject.integralrule.IntegralRuleDO;
import co.yixiang.yshop.module.member.enums.BillDetailEnum;
import co.yixiang.yshop.module.member.service.integralrule.IntegralRuleService;
import co.yixiang.yshop.module.member.service.integralrule.strategy.impl.DefaultIntegralRuleStrategy;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author pepis
 * @apiNote 积分奖励规则上下文
 **/
@Component
public class IntegralRuleContext {
    private final Map<String, IntegralRuleStrategy> map = SpringUtil.getBeansOfType(IntegralRuleStrategy.class);
    @Resource
    private DefaultIntegralRuleStrategy defaultIntegralRuleStrategy;
    @Resource
    private IntegralRuleService integralRuleService;

    public BigDecimal execute(BillDetailEnum type, IntegralRuleDTO rule) {
        IntegralRuleStrategy integralRuleStrategy = map.getOrDefault(type.getValue(), defaultIntegralRuleStrategy);
        return integralRuleStrategy.execute(type, rule);
    }

    public BigDecimal execute(BillDetailEnum type, Long userId) {
        return this.execute(type, userId, null);
    }

    public BigDecimal execute(BillDetailEnum type, Long userId, BigDecimal consumeAmount) {
        List<IntegralRuleDO> integralRuleByTypes = integralRuleService.getIntegralRuleByTypes(Collections.singletonList(type.getValue()));
        if (CollectionUtil.isEmpty(integralRuleByTypes)) {
            return null;
        } else {
            IntegralRuleDO integralRuleDO = integralRuleByTypes.get(0);
            IntegralRuleDTO rule = new IntegralRuleDTO();
            rule.setUserId(userId);
            rule.setIntegral(integralRuleDO.getIntegral());
            rule.setType(integralRuleDO.getType());
            rule.setAttribute1(integralRuleDO.getAttribute1());
            rule.setEnable(integralRuleDO.getEnable());
            rule.setConsumeAmount(consumeAmount);
            return this.execute(type, rule);
        }
    }
}
