package com.hzs.activity.base.provider;

import cn.hutool.core.collection.CollectionUtil;
import com.hzs.activity.base.IActivityServiceApi;
import com.hzs.activity.base.param.GiftConfigParam;
import com.hzs.activity.base.param.GiftConfigParamDetail;
import com.hzs.activity.base.service.IActivityService;
import com.hzs.activity.consume.service.IAcConsumeRuleConfigService;
import com.hzs.activity.draw.service.IAcDrawRewardNumService;
import com.hzs.activity.policy.service.IAcPolicyConfigService;
import com.hzs.activity.recoilGive.service.IAcRecoilGiveConfigService;
import com.hzs.activity.recommend.service.IAcRepurCouponsRuleConfigService;
import com.hzs.activity.register.service.IAcRegisterGiftService;
import com.hzs.activity.wares.service.IAcWaresRuleConfigService;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.EActType;
import com.hzs.common.core.enums.EYesNo;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.activity.base.ext.AcGiftConfigExt;
import com.hzs.common.domain.activity.consume.ext.AcConsumeRuleConfigExt;
import com.hzs.common.domain.activity.wares.ext.AcWaresRuleConfigExt;
import com.hzs.common.domain.sale.ext.BdWaresDetailExt;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 所有活动的生效，获得赠品入口
 */
@Slf4j
@DubboService
public class ActivityServiceProvider implements IActivityServiceApi {

    @Autowired
    private IAcWaresRuleConfigService acWaresRuleConfigService;
    @Autowired
    private IAcConsumeRuleConfigService acConsumeRuleConfigService;
    @Autowired
    private IAcDrawRewardNumService acDrawRewardNumService;
    @Autowired
    private IActivityService activityService;
    @Autowired
    private IAcPolicyConfigService iAcPolicyConfigService;
    @Autowired
    private IAcRecoilGiveConfigService iAcRecoilGiveConfigService;

    @Override
    public R<List<BdWaresDetailExt>> generateActivityGiftWaresAchieve(Integer specialArea, Integer pkCountry, List<BdWaresDetailExt> bdWaresDetailExtList) {
        // 买赠活动
        Date currentDate = DateUtils.currentDate();
        GiftConfigParam giftConfigParam = GiftConfigParam.builder()
                .actType(EActType.PRODUCT_GIFT.getValue())
                .orderType(specialArea)
                .startDate(currentDate)
                .endDate(currentDate)
                .orderAmount(BigDecimal.ZERO)
                .orderAchieve(BigDecimal.ZERO)
                .pkCountry(pkCountry)
                .build();
        List<GiftConfigParamDetail> configParamDetailList = new ArrayList<>(bdWaresDetailExtList.size());
        for (BdWaresDetailExt bdWaresDetailExt : bdWaresDetailExtList) {
            GiftConfigParamDetail giftConfigParamDetail = GiftConfigParamDetail.builder()
                    .pkWares(bdWaresDetailExt.getPkWares())
                    .quantity(bdWaresDetailExt.getWaresQuantity())
                    .build();
            configParamDetailList.add(giftConfigParamDetail);
        }
        giftConfigParam.setConfigParamDetailList(configParamDetailList);
        List<BdWaresDetailExt> returnBdWaresDetailList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(giftConfigParam.getConfigParamDetailList())) {
            List<AcWaresRuleConfigExt> waresRuleConfigExtList = acWaresRuleConfigService.queryWaresGiftConfigByCondition(giftConfigParam);
            if (CollectionUtil.isNotEmpty(waresRuleConfigExtList)) {
                for (AcWaresRuleConfigExt waresRuleConfigExt : waresRuleConfigExtList) {
                    // 遍历购买的商品，判断是否在规则内
                    for (BdWaresDetailExt bdWaresDetail : bdWaresDetailExtList) {
                        // 指定商品买多少件
                        if (bdWaresDetail.getPkWares().equals(waresRuleConfigExt.getPkWares())) {
                            // TODO cabbage 目前这个位置需要优化，多活动多规则不支持，此处只匹配了同商品数量配置最小的
                            AcGiftConfigExt acGiftConfigExt = waresRuleConfigExt.getGiftConfigExtList().get(0);
                            // 实际需要赠送的商品数量（购买的商品数量 整除 活动配置的商品数量 = 实际赠送商品数量）
                            // 例：买3赠2的活动（购买的商品数量6 整除 活动配置商品数量3 = 实际赠品商品数量2份）
                            int waresQuantity = bdWaresDetail.getWaresQuantity() / waresRuleConfigExt.getQuantity();
                            if (waresQuantity > 0) {
                                // 如果购买的数量达不到配置的商品数量，则不需要进行赠品处理
                                BdWaresDetailExt bdWaresDetailExt = BdWaresDetailExt.builder()
                                        .isFreeMail(waresRuleConfigExt.getIsFreeMail())
                                        .pkAirPostage(waresRuleConfigExt.getPkAirPostage())
                                        .pkLandPostage(waresRuleConfigExt.getPkLandPostage())
                                        .pkOceanPostage(waresRuleConfigExt.getPkOceanPostage())
                                        .waresQuantity(1)
                                        .build();

                                // 实际赠送商品数量 * 配置产品赠送数量 = 实际赠品数量
                                // 例：实际赠品商品数量2份 * 配置产品赠送数量2 = 实际赠品数量4
                                acGiftConfigExt.setQuantity(waresQuantity * acGiftConfigExt.getQuantity());
                                packageWaresDetail(bdWaresDetailExt, acGiftConfigExt);
                                returnBdWaresDetailList.add(bdWaresDetailExt);
                            }
                        }
                    }
                }
            }
        }

        // 消费赠送
        giftConfigParam.setActType(EActType.CONSUMPTION_GIFT.getValue());
        for (BdWaresDetailExt bdWaresDetailExt : bdWaresDetailExtList) {
            // 业绩、金额累积
            giftConfigParam.setOrderAmount(ComputeUtil.computeAdd(giftConfigParam.getOrderAmount(), ComputeUtil.computeMultiply(ComputeUtil.computeMultiply(bdWaresDetailExt.getPrice(), bdWaresDetailExt.getQuantity()), bdWaresDetailExt.getWaresQuantity())));
            giftConfigParam.setOrderAchieve(ComputeUtil.computeAdd(giftConfigParam.getOrderAchieve(), ComputeUtil.computeMultiply(ComputeUtil.computeMultiply(bdWaresDetailExt.getAchieve(), bdWaresDetailExt.getQuantity()), bdWaresDetailExt.getWaresQuantity())));
        }
        List<AcConsumeRuleConfigExt> consumeRuleConfigExtList = acConsumeRuleConfigService.queryConsumeGiftConfigByCondition(giftConfigParam);
        if (consumeRuleConfigExtList != null && consumeRuleConfigExtList.size() > 0) {
            for (AcConsumeRuleConfigExt consumeRuleConfigExt : consumeRuleConfigExtList) {
                // 配置ID
                Long pkConfigId = consumeRuleConfigExt.getGiftConfigExtList().get(0).getPkId();

                // 同一活动匹配多条规则，同规则下可能有多个赠品
                for (AcGiftConfigExt giftConfigExt : consumeRuleConfigExt.getGiftConfigExtList()) {
                    if (pkConfigId.equals(giftConfigExt.getPkId())) {
                        BdWaresDetailExt bdWaresDetailExt = BdWaresDetailExt.builder()
                                .isFreeMail(EYesNo.YES.getIntValue())
                                .waresQuantity(1)
                                .build();
                        packageWaresDetail(bdWaresDetailExt, giftConfigExt);
                        returnBdWaresDetailList.add(bdWaresDetailExt);
                    }
                }
            }
        }

        return R.ok(returnBdWaresDetailList);
    }

    /*
     *  封装赠品明细
     **/
    private void packageWaresDetail(BdWaresDetailExt bdWaresDetailExt, AcGiftConfigExt acGiftConfigExt) {
        bdWaresDetailExt.setPkProduct(acGiftConfigExt.getPkProduct());
        bdWaresDetailExt.setPkWares(0);
        bdWaresDetailExt.setPkId(0);
        bdWaresDetailExt.setPkWaresSpecsSku(0);
        bdWaresDetailExt.setPrice(BigDecimal.ZERO);
        bdWaresDetailExt.setAchieve(BigDecimal.ZERO);
        bdWaresDetailExt.setAssAchieve(BigDecimal.ZERO);
        bdWaresDetailExt.setQuantity(acGiftConfigExt.getQuantity());
        bdWaresDetailExt.setIsGift(EYesNo.YES.getIntValue());
        bdWaresDetailExt.setSpecsName(acGiftConfigExt.getSpecsName());
        bdWaresDetailExt.setSpecsNameId(acGiftConfigExt.getSpecsNameId());
    }

    @Override
    public R<Boolean> handleActivity(SaOrderExt saOrderExt) {
        try {
            if (activityService.handleActivity(saOrderExt)) {
                return R.ok();
            }
            return R.fail("活动处理失败");
        } catch (Exception e) {
            log.error("订单处理活动异常 {}", e.getMessage(), e);
            return R.fail("活动处理异常： " + e.getMessage());
        }
    }

    @Override
    public R<Boolean> backGiveMemberDrawNum(SaOrderExt saOrderExt) {
        try {
            return R.ok(acDrawRewardNumService.backGiveMemberDrawNum(saOrderExt));
        } catch (Exception e) {
            log.error("{}", e.getMessage(), e);
            return R.fail();
        }
    }

    @Override
    public R<Boolean> backGiveOrderPolicy(SaOrderExt saOrderExt) {
        try {
            iAcPolicyConfigService.backOrderPolicyActivity(saOrderExt);
            return R.ok();
        } catch (Exception e) {
            log.error("撤销订单回退政策币处理异常，{}", e.getMessage(), e);
            return R.fail("撤销订单回退政策币处理异常，" + e.getMessage());
        }
    }

    @Override
    public R<Boolean> recoilGiveHandle(SaOrderExt saOrderExt) {
        try {
            String str = iAcRecoilGiveConfigService.recoilGiveHandle(saOrderExt);
            if (null == str) {
                return R.ok();
            }
            return R.fail(str);
        } catch (Exception e) {
            log.error("订单消费币赠送活动处理异常，{}", e.getMessage(), e);
            return R.fail("订单消费币赠送活动处理异常，" + e.getMessage());
        }
    }

    @Override
    public R<Boolean> recoilGiveCancelHandle(SaOrderExt saOrderExt) {
        try {
            String str = iAcRecoilGiveConfigService.recoilGiveCancelHandle(saOrderExt);
            if (null == str) {
                return R.ok();
            }
            return R.fail(str);
        } catch (Exception e) {
            log.error("订单消费币赠送活动撤单处理异常，{}", e.getMessage(), e);
            return R.fail("订单消费币赠送活动撤单处理异常，" + e.getMessage());
        }
    }

}
