package cn.freemud.service.impl.mcoffee.calculation;

import cn.freemud.adapter.ActivityAdapter;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityChannelEnum;
import cn.freemud.enums.CouponFlag;
import cn.freemud.enums.ResponseResult;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.CommonService;
import cn.freemud.service.thirdparty.ActivityClient;
import cn.freemud.utils.PropertyConvertUtil;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.membercenter.request.QueryReceiveAddressRequest;
import com.freemud.application.sdk.api.membercenter.response.QueryReceiveAddressResponse;
import com.freemud.application.sdk.api.membercenter.service.MemberCenterService;
import com.freemud.application.sdk.api.storecenter.request.QueryDeliveryRequest;
import com.freemud.application.sdk.api.storecenter.response.QueryDeliverDetailResponse;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
import com.freemud.sdk.api.assortment.shoppingcart.enums.BusinessTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: CalculationServiceImpl
 * @Package cn.freemud.service.impl
 * @Description:
 * @author: shuhu.hou
 * @date: 2020/6/11 17:06
 * @Copyright: 2020 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */

@Slf4j
@Service
public class CalculationServiceImpl {


    @Autowired
    private MemberCenterService memberCenterService;
    @Autowired
    private StoreCenterService storeCenterService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private ActivityClient activityClient;
    @Autowired
    private ActivityAdapter activityAdapter;


    @Autowired
    private TimeSaleCalculation timeSaleCalculation;
    @Autowired
    private FullPromotionCalculation fullPromotionCalculation;
    @Autowired
    private CouponDiscountCalculation couponDiscountCalculation;

    /**
     * 更新购物车行优惠信息
     */
    public void updateShoppingCartGoodsDiscount(String partnerId, String storeId, String userId, String appId, Integer orderType,
                                                boolean isMember, String menuType, String receiveId,
                                                List<CartGoods> cartGoodsList, List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons,
                                                List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {

        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, appId, shoppingCartGoodsResponseVo);


        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, orderType);

        ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscount = getCalculationDiscount(partnerId, storeId, userId, appId, orderType, isMember,
                menuType, deliveryAmount, cartGoodsList, coupons, sendGoodsList);
        updateDiscount(calculationDiscount, cartGoodsList, shoppingCartGoodsResponseVo);
        //满减
        fullPromotionCalculation.updateShoppingCartGoodsDiscount(activityQueryDto, calculationDiscount, cartGoodsList, shoppingCartGoodsResponseVo);
        //限时特价
        timeSaleCalculation.TimeSaleUpdateShoppingCartGoodsDiscount(calculationDiscount, cartGoodsList, shoppingCartGoodsResponseVo);


        CouponPromotionVO couponPromotionVO = new CouponPromotionVO();
        couponPromotionVO.setPartnerId(partnerId);
        couponPromotionVO.setUserId(userId);
        couponPromotionVO.setStoreId(storeId);
        couponPromotionVO.setCouponCode(null);
        couponPromotionVO.setOrderType(orderType);
        couponPromotionVO.setFlg(CouponFlag.YES.getCode());
        //优惠券
        couponDiscountCalculation.updateShoppingCartGoodsDiscountCoupon(couponPromotionVO,calculationDiscount,cartGoodsList, shoppingCartGoodsResponseVo);
    }


    public ActivityCalculationDiscountResponseDto.CalculationDiscountResult getCalculationDiscount(
            String partnerId, String storeId, String userId, String appId, Integer orderType, boolean isMember, String menuType, Long deliveryAmount,
            List<CartGoods> cartGoodsList, List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons, List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList) {

        List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList = new ArrayList<>();
        for (CartGoods cartGoods : cartGoodsList) {
            addCalculationDiscountGoods(calculationDiscountGoodsList, cartGoods.getGoodsId(), cartGoods.getQty(), cartGoods.getFinalPrice(), cartGoods.getMemberDiscount());
        }

        if (BusinessTypeEnum.SAAS_DELIVERY.getCode().equals(menuType)) {
            deliveryAmount = null;
        }
        // 当加价购商品不为空时
        if (CollectionUtils.isNotEmpty(sendGoodsList)) {
            for (ShoppingCartInfoRequestVo.SendGoods sendGoods : sendGoodsList) {
                this.addCalculationDiscountGoods(calculationDiscountGoodsList, sendGoods.getGoodsId(), sendGoods.getQty(), sendGoods.getOriginalPrice(), 100);
            }
        }
        calculationDiscountGoodsList.removeIf(calculationDiscountGoods -> (calculationDiscountGoods.getGoodsQuantity().equals(0)));
        if (CollectionUtils.isEmpty(calculationDiscountGoodsList)) {
            return null;
        }

        ActivityCalculationDiscountRequestDto discountRequest = getActivityCalculationDiscountRequestDto(partnerId, storeId, userId, appId, orderType);
        discountRequest.setGoods(calculationDiscountGoodsList);
        discountRequest.setCoupons(coupons);
        discountRequest.setOrgIds(commonService.getOrgIds(partnerId, storeId));
        discountRequest.setDistributionFee(deliveryAmount);
        discountRequest.setIsMember(isMember);
        ActivityCalculationDiscountResponseDto activityCalculationDiscountResponseDto;
        try {
            activityCalculationDiscountResponseDto = activityClient.calculationDiscountSharing(discountRequest);
        } catch (Exception ex) {
            ErrorLog.printErrorLog("calculation_discount_error", "/calculation/discount/sharding", discountRequest, ex);
            throw new ServiceException(ResponseResult.OPERATE_TOO_OFTEN);
        }
        // 返回成功
        if (activityCalculationDiscountResponseDto == null || !StringUtils.equals(activityCalculationDiscountResponseDto.getStatusCode(), ResponseCodeConstant.RESPONSE_SUCCESS_STR)) {
            throw new ServiceException(ResponseResult.OPERATE_TOO_OFTEN);
        }
        return activityCalculationDiscountResponseDto.getResult();
    }












    /**
     * 配送金额
     */
    private Long calculateDeliveryAmount(String receiveId, String partnerId, String storeId, String wxappid, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {
        Long deliveryAmount = 0L;
        if (StringUtils.isBlank(receiveId)) {
            return deliveryAmount;
        }
        log.info("获取配送配逻辑 tackingNo:{},receiveId:{},partnerId:{},storeId:{}", LogThreadLocal.getTrackingNo(), receiveId, partnerId, storeId);

        String trackingNo = LogThreadLocal.getTrackingNo();

        QueryReceiveAddressRequest queryReceive = new QueryReceiveAddressRequest(receiveId, partnerId);
        //查询会员后货地址经纬度
        com.freemud.application.sdk.api.base.BaseResponse<QueryReceiveAddressResponse> queryReceiveAddressResponse = memberCenterService.queryReceiveAddressById(queryReceive, trackingNo);
        if (!ResponseResult.SUCCESS.getCode().equals(queryReceiveAddressResponse.getCode()) || queryReceiveAddressResponse.getData() == null) {
            throw new ServiceException(ResponseResult.USER_GETRECEIVEADDRESS_ERROR);
        }

        QueryDeliveryRequest queryDeliveryRequest = new QueryDeliveryRequest();
        queryDeliveryRequest.setPartnerId(partnerId);
        queryDeliveryRequest.setStoreCode(storeId);
        queryDeliveryRequest.setUserLatitude(queryReceiveAddressResponse.getData().getLatitude());
        queryDeliveryRequest.setUserLongitude(queryReceiveAddressResponse.getData().getLongitude());
        com.freemud.application.sdk.api.base.BaseResponse<QueryDeliverDetailResponse> queryDeliverDetailResponse = storeCenterService.queryDeliverDetail(queryDeliveryRequest, trackingNo);
        if (queryDeliverDetailResponse == null || !ResponseResult.SUCCESS.getCode().equals(queryDeliverDetailResponse.getCode()) || queryDeliverDetailResponse.getData() == null) {
            throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
        }
        if (queryDeliverDetailResponse.getData().getDeliveryAmount() == null) {
            throw new ServiceException(ResponseResult.STORE_DELIVERY_AMOUNT_ERROR);
        }
        shoppingCartGoodsResponseVo.setDeliveryFeeZeroReason(queryDeliverDetailResponse.getData().getDeliveryFeeZeroReason() != null ? queryDeliverDetailResponse.getData().getDeliveryFeeZeroReason() : 0);
        deliveryAmount = queryDeliverDetailResponse.getData().getDeliveryAmount();

        return deliveryAmount;
    }


    /**
     * 构建 ActivityCalculationDiscountRequestDto
     *
     * @param partnerId
     * @param storeId
     * @param userId
     * @param appId
     * @param orderType
     * @return
     */
    private ActivityCalculationDiscountRequestDto getActivityCalculationDiscountRequestDto(String partnerId, String storeId, String userId, String appId, Integer orderType) {
        ActivityCalculationDiscountRequestDto activityCalculationDiscountRequestDto = new ActivityCalculationDiscountRequestDto();
        activityCalculationDiscountRequestDto.setPartnerCode(partnerId);
        activityCalculationDiscountRequestDto.setStoreId(storeId);
        activityCalculationDiscountRequestDto.setIsShowGoodsActivity(1);
        activityCalculationDiscountRequestDto.setUserId(userId);
        activityCalculationDiscountRequestDto.setVer(1);
        activityCalculationDiscountRequestDto.setAppId(appId);
        ActivityChannelEnum activityChannelEnum = PropertyConvertUtil.orderTypeConvert2ActivityChannel(orderType);
        if (!Objects.isNull(activityChannelEnum)) {
            activityCalculationDiscountRequestDto.setChannel(activityChannelEnum.getCode());
        }
        return activityCalculationDiscountRequestDto;
    }

    /**
     * 将calculationDiscountGoods 封装后加入 calculationDiscountGoodsList
     *
     * @param calculationDiscountGoodsList
     * @param goodsId
     * @param goodsQuantity
     * @param originalPrice
     */
    private void addCalculationDiscountGoods(List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList,
                                             String goodsId, Integer goodsQuantity, Long originalPrice, Integer memberDiscount) {
        ActivityCalculationDiscountRequestDto.CalculationDiscountGoods calculationDiscountGoods = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods();
        calculationDiscountGoods.setGoodsId(goodsId);
        calculationDiscountGoods.setGoodsQuantity(goodsQuantity);
        calculationDiscountGoods.setOriginalPrice(originalPrice);
        calculationDiscountGoods.setMemberDiscount(memberDiscount);

        //累加需加入计算的商品
        int index;
        // 当商品已存在时,需累加数量
        if ((index = calculationDiscountGoodsList.indexOf(calculationDiscountGoods)) >= 0) {
            ActivityCalculationDiscountRequestDto.CalculationDiscountGoods oldCalculationDiscountGoods = calculationDiscountGoodsList.get(index);
            oldCalculationDiscountGoods.setGoodsQuantity(oldCalculationDiscountGoods.getGoodsQuantity() + calculationDiscountGoods.getGoodsQuantity());
        } else {
            calculationDiscountGoodsList.add(calculationDiscountGoods);
        }
    }


    private void updateDiscount(ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscount, List<CartGoods> cartGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {
        long totalOriginalAmount = 0L;
        long totalAmount = 0L;
        long totalPackgeAmount = 0L;
        for (CartGoods cartGoods : cartGoodsList) {
            // 设置商品原价与商品现价的初始值
            long originalAmount = cartGoods.getOriginalPrice() * cartGoods.getQty();
            long amount = cartGoods.getOriginalPrice() * cartGoods.getQty();
            long packAmount = cartGoods.getPackPrice() * cartGoods.getQty();
            totalOriginalAmount += originalAmount;
            totalAmount += amount;
            totalPackgeAmount += packAmount;
            cartGoods.setOriginalAmount(originalAmount);
            cartGoods.setAmount(amount);
            cartGoods.setPackPrice(packAmount);
        }
        shoppingCartGoodsResponseVo.setOriginalTotalAmount(calculationDiscount == null ? totalOriginalAmount : calculationDiscount.getOriginalTotalAmount());
        shoppingCartGoodsResponseVo.setTotalAmount(calculationDiscount == null ? totalAmount : calculationDiscount.getTotalAmount());
        shoppingCartGoodsResponseVo.setNewPackAmount(totalPackgeAmount);
        shoppingCartGoodsResponseVo.setTotalDiscountAmount(calculationDiscount == null ? 0L : calculationDiscount.getTotalDiscountAmount());
    }


}
