package cn.freemud.service.impl;

import cn.freemud.adapter.PromotionAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.promotion.*;
import cn.freemud.entities.vo.ProductVo;
import cn.freemud.entities.vo.encircle.CreateReserveOrderVo;
import cn.freemud.entities.vo.encircle.PreviewOrderInfoVo;
import cn.freemud.service.CommonService;
import cn.freemud.service.thirdparty.PromotionDiscountClient;
import cn.freemud.utils.SpringBeanUtil;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.ordercenter.enums.ProductTypeEnum;
import com.freemud.application.sdk.api.storecenter.request.vo.GetOrgTreeListRequest;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
import com.freemud.sdk.api.assortment.order.response.order.QueryOrdersResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * All rights Reserved, Designed By www.freemud.com
 *
 * @version V1.0
 * @Title:
 * @Package: com.freemud.sdk.api.assortment.promotion.service
 * @Descripttion:
 * @author: cuigenyou
 * @date: 2019/9/9 10:18
 * @Copyright: 2017 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目.
 */
@Service
public class ActivityCalculationDiscountService {

    private static Logger logger = LoggerFactory.getLogger(ActivityCalculationDiscountService.class);

    private final static String RESPONSE_SUCCESS_STR = "100";

    @Autowired
    private PromotionDiscountClient promotionDiscountClient;
    @Autowired
    private StoreCenterService storeCenterService;
    @Autowired
    private DefaultPromotionService defaultPromotionService;
    @Autowired
    private SetMealPromotionService setMealPromotionService;
    @Autowired
    private CouponPromotionService couponPromotionService;
    @Autowired
    private FullPromotionService fullPromotionService;
    @Autowired
    private TimeSalePromotionService timeSalePromotionService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private CustomerScoreService customerScoreService;


    public ShoppingCartGoodsResponse updateDiscountApportion(OrderBeanRequest request, CouponPromotionDto couponPromotionDto,Boolean isApportion) {
        ShoppingCartGoodsResponse shoppingCartGoodsResponse = new ShoppingCartGoodsResponse();

        List<CalculationCouponDto> coupons = new ArrayList<>();
        // 当couponCode不为空时，需参与价格计算
        if (StringUtils.isNotEmpty(couponPromotionDto.getCouponCode())) {
            CalculationCouponDto coupon = new CalculationCouponDto();
            coupon.setCode(couponPromotionDto.getCouponCode());
            coupon.setActivityCode(couponPromotionDto.getActivityCode());
            coupons.add(coupon);
        }

        ActivityQueryDto activityQueryDto = ActivityQueryDto.builder().partnerId(request.getCompanyId())
                .storeId(request.getShopId())
                .userId(request.getUserId())
                .appId(request.getAppId())
                .orderType(request.getOrderType())
                .build();

        CalculationDiscountResultDto calculationDiscountResultDto = getCalculationResult(request, coupons);
        logger.info("促销分摊:{}",calculationDiscountResultDto);
        // 默认计算
        defaultPromotionService.updateDiscountApportion(shoppingCartGoodsResponse, request, calculationDiscountResultDto, couponPromotionDto, activityQueryDto, isApportion);
        // 套餐计算
        setMealPromotionService.updateDiscountApportion(shoppingCartGoodsResponse, request, calculationDiscountResultDto, couponPromotionDto, activityQueryDto, isApportion);
        // 优惠券计算
        couponPromotionService.updateDiscountApportion(shoppingCartGoodsResponse, request, calculationDiscountResultDto, couponPromotionDto, activityQueryDto, isApportion);
        // 满减
        fullPromotionService.updateDiscountApportion(shoppingCartGoodsResponse, request, calculationDiscountResultDto, couponPromotionDto, activityQueryDto, isApportion);
        // 限时特价
        timeSalePromotionService.updateDiscountApportion(shoppingCartGoodsResponse, request, calculationDiscountResultDto, couponPromotionDto, activityQueryDto, isApportion);
        logger.info("限时特价shoppingCartGoodsResponse:{}",shoppingCartGoodsResponse);
        // 积分抵扣
        customerScoreService.updateDiscountApportion(shoppingCartGoodsResponse, request, calculationDiscountResultDto, couponPromotionDto, activityQueryDto, isApportion);
        return shoppingCartGoodsResponse;
    }

    private CalculationDiscountResultDto getCalculationResult(OrderBeanRequest request, List<CalculationCouponDto> coupons) {
        // 1.组装促销计算request
        CalculationDiscountRequestDto activityCalculationDiscountRequestDto = PromotionAdapter.getActivityCalculationDiscountRequestDto(request.getCompanyId(), request.getShopId(), request.getUserId(), request.getAppId(), request.getOrderType());
        List<CalculationDiscountGoodsDto> calculationDiscountGoodsList = new ArrayList<>();

        for(OrderBeanRequest.ProductBean orderProductBean : request.getProductList()) {
            if(isWeightProduct(orderProductBean)) {
                continue;
            }
            if (ProductTypeEnum.SETMEAL_PRODUCT.getCode().equals(orderProductBean.getProductType()) || ProductTypeEnum.SETMEAL_UPPRICE_PRODUCT.getCode().equals(orderProductBean.getProductType())) {
                Long productGroupSettlementPrice = orderProductBean.getComboProduct().stream().filter(o -> !o.getIsFixedProduct()).mapToLong(OrderBeanRequest.ProductBean::getSettlementPrice).sum();
                Long nowPrice = (orderProductBean.getSettlementPrice() - productGroupSettlementPrice) / orderProductBean.getNumber();
                PromotionAdapter.addCalculationDiscountGoods(calculationDiscountGoodsList, orderProductBean.getProductId(), orderProductBean.getNumber(), nowPrice.intValue());
            } else {
                Long nowPrice = orderProductBean.getSettlementPrice() / orderProductBean.getNumber();
                PromotionAdapter.addCalculationDiscountGoods(calculationDiscountGoodsList, orderProductBean.getProductId(), orderProductBean.getNumber(), nowPrice.intValue());
            }
        }
        calculationDiscountGoodsList.removeIf(calculationDiscountGoods -> (calculationDiscountGoods.getGoodsQuantity().equals(0)));
        if (CollectionUtils.isEmpty(calculationDiscountGoodsList)) {
            return null;
        }
        activityCalculationDiscountRequestDto.setGoods(calculationDiscountGoodsList);
        activityCalculationDiscountRequestDto.setCoupons(coupons);
        activityCalculationDiscountRequestDto.setOrgIds(commonService.getOrgIds(request.getCompanyId(), request.getShopId()));
        // 2.调用促销计算接口，结算促销结果
        CalculationDiscountResponseDto calculationDiscountResponseDto = null;
        try {
            calculationDiscountResponseDto = promotionDiscountClient.discountSharing(activityCalculationDiscountRequestDto);
        } catch (Exception ex) {
            ErrorLog.printErrorLog("promotionCalculationDiscountError", "/calculation/discount/sharing", activityCalculationDiscountRequestDto, ex);
            return null;
        }
        if (calculationDiscountResponseDto == null || !StringUtils.equals(calculationDiscountResponseDto.getStatusCode(), RESPONSE_SUCCESS_STR)) {
            return null;
        }
        return calculationDiscountResponseDto.getResult();
    }


    private boolean isWeightProductNoWeight(OrderBeanRequest.ProductBean orderProductBean) {
        if(Objects.equals(orderProductBean.getProductType(), ProductTypeEnum.WEIGHT_PRODUCT.getCode()) && new BigDecimal("0").compareTo(orderProductBean.getWeight()) >=0) {
            return true;
        }
        if(Objects.equals(orderProductBean.getProductType(), ProductTypeEnum.SETMEAL_PRODUCT.getCode()) || Objects.equals(orderProductBean.getProductType(), ProductTypeEnum.SETMEAL_UPPRICE_PRODUCT.getCode())) {
            if(CollectionUtils.isNotEmpty(orderProductBean.getComboProduct())) {
                for (OrderBeanRequest.ProductBean productBean : orderProductBean.getComboProduct()) {
                    if(Objects.equals(productBean.getProductType(), ProductTypeEnum.WEIGHT_PRODUCT.getCode()) && new BigDecimal("0").compareTo(productBean.getWeight()) >=0) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private boolean isWeightProduct(OrderBeanRequest.ProductBean orderProductBean) {
        if(Objects.equals(orderProductBean.getProductType(), ProductTypeEnum.WEIGHT_PRODUCT.getCode())) {
            return true;
        }
        if(Objects.equals(orderProductBean.getProductType(), ProductTypeEnum.SETMEAL_PRODUCT.getCode()) || Objects.equals(orderProductBean.getProductType(), ProductTypeEnum.SETMEAL_UPPRICE_PRODUCT.getCode())) {
            if(CollectionUtils.isNotEmpty(orderProductBean.getComboProduct())) {
                for (OrderBeanRequest.ProductBean productBean : orderProductBean.getComboProduct()) {
                    if(Objects.equals(productBean.getProductType(), ProductTypeEnum.WEIGHT_PRODUCT.getCode())) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public void updatePreviewOrderInfoVo(PreviewOrderInfoVo previewOrderInfoVo, ShoppingCartGoodsResponse shoppingCartGoodsResponse) {
        if(shoppingCartGoodsResponse == null) {
            return;
        }
        previewOrderInfoVo.setDiscountTotalAmount(shoppingCartGoodsResponse.getTotalDiscountAmount());
        previewOrderInfoVo.setAmount(shoppingCartGoodsResponse.getTotalAmount());
        previewOrderInfoVo.setAvailableCoupon(shoppingCartGoodsResponse.getAvailableCoupon());
        previewOrderInfoVo.setFullDiscount(shoppingCartGoodsResponse.getFullDiscount());
        previewOrderInfoVo.setCouponDiscount(shoppingCartGoodsResponse.getCouponDiscount());
        previewOrderInfoVo.setToastMsg(shoppingCartGoodsResponse.getToastMsg());
        previewOrderInfoVo.setActivityTip(shoppingCartGoodsResponse.getActivityTip());
        previewOrderInfoVo.setCustomerScoreVo(shoppingCartGoodsResponse.getCustomerScoreVo());
        //循环促销计算商品信息，保存订单金额信息
        if(CollectionUtils.isNotEmpty(previewOrderInfoVo.getProducts())){
            for (ProductVo productVo : previewOrderInfoVo.getProducts()) {
                ShoppingCartGoodsResponse.CartGoodsDetailDto cartGoodsDetailDto = shoppingCartGoodsResponse.getProducts().stream().filter(t -> ObjectUtils.equals(productVo.getPid(), t.getProductId()) && productVo.getSequence() == t.getSequence()).findFirst().orElse(null);
                if(cartGoodsDetailDto != null) {
                    productVo.setSaleTotalAmount(cartGoodsDetailDto.getOriginalTotalAmount() - cartGoodsDetailDto.getTotalDiscountAmount());
                    productVo.setFinalPrice(cartGoodsDetailDto.getFinalPrice());
                    productVo.setOriginalTotalAmount(cartGoodsDetailDto.getOriginalTotalAmount());
                    if ((ProductTypeEnum.SETMEAL_PRODUCT.getCode() == productVo.getProductType() || ProductTypeEnum.SETMEAL_UPPRICE_PRODUCT.getCode() == productVo.getProductType())
                            && CollectionUtils.isNotEmpty(productVo.getSetMealProducts())) {
                        productVo.getSetMealProducts().stream().forEach(p -> {
                            ShoppingCartGoodsResponse.CartGoodsDetailDto combCartGoods = cartGoodsDetailDto.getComboList().stream().filter(t -> t.getProductId().equals(p.getPid()) && t.getSequence().equals(p.getSequence())).findFirst().orElse(null);
                            p.setSaleTotalAmount(combCartGoods.getOriginalTotalAmount() - combCartGoods.getTotalDiscountAmount());
                            p.setFinalPrice(combCartGoods.getFinalPrice());
                            p.setOriginalTotalAmount(combCartGoods.getOriginalTotalAmount());
                        });
                    }
                }
            }
        }
    }

}
