package cn.freemud.demo.service.impl;

import cn.freemud.adapter.CouponAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.demo.adapter.service.CheckAdapter;
import cn.freemud.demo.adapter.service.DistributeAdapter;
import cn.freemud.demo.entities.bo.CheckAdapterBO;
import cn.freemud.demo.entities.bo.DistributeAdapterBO;
import cn.freemud.demo.entities.bo.GetCalCostBO;
import cn.freemud.demo.entities.bo.goods.ValidateShopProductRequestBO;
import cn.freemud.demo.entities.bo.goods.ShoppingCartGoodsBO;
import cn.freemud.demo.entities.bo.goods.*;
import cn.freemud.demo.entities.bo.goods.list.ListCartGoodsBO;
import cn.freemud.demo.entities.bo.promotion.GetCalculationDiscountBO;
import cn.freemud.demo.entities.bo.store.GetStoreBO;
import cn.freemud.demo.manager.customer.CustomerManager;
import cn.freemud.demo.manager.product.ProductManager;
import cn.freemud.demo.manager.store.StoreManager;
import cn.freemud.demo.service.impl.AbstractListCartGoodsService;
import cn.freemud.demo.utils.CommonUtils;
import cn.freemud.entities.dto.ActivityCalculationDiscountResponseDto;
import cn.freemud.entities.dto.CheckSpqInfoRequestDto;
import cn.freemud.entities.dto.CheckSpqInfoResponseDto;
import cn.freemud.entities.vo.ActivityClassifyCouponBean;
import cn.freemud.entities.vo.CartGoods;
import cn.freemud.entities.vo.CouponPromotionVO;
import cn.freemud.entities.vo.ShoppingCartInfoRequestVo;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.CouponService;
import cn.freemud.utils.PropertyConvertUtil;
import com.freemud.application.sdk.api.log.ApiLog;
import com.freemud.application.sdk.api.productcenter.request.product.valid.ValidateShopProductType;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CommonsConstant;
import com.freemud.sdk.api.assortment.shoppingcart.enums.BusinessTypeEnum;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

@Service
public class PlatformListCartGoodsService extends AbstractListCartGoodsService {

    @Autowired
    private CouponService couponService;

    @Autowired
    private CouponAdapter couponAdapter;

    @Autowired
    private DistributeAdapter distributeAdapter;

    @Autowired
    private cn.freemud.demo.adapter.service.CalculationSharingAdapter calculationSharingAdapter;

    @Autowired
    private CheckAdapter checkAdapter;

    @Override
    public BaseResponse checkCustomParams(ListCartGoodsBO baseRequestDTO) {

        return ResponseBuilder.success();
    }

    @Override
    public CalCostBO getDiscountResultBefore(ListCartGoodsBO baseRequestDTO, DiscountResultBO discountResultBO) {
        GetCalCostBO bo = new GetCalCostBO();
        bo.setPartnerId(baseRequestDTO.getPartnerId());
        bo.setReceiveId(baseRequestDTO.getReceiveId());
        bo.setShopId(baseRequestDTO.getShopId());
        bo.setOrderType(baseRequestDTO.getOrderType());
        bo.setManagerService(baseRequestDTO.getManagerService());


        bo.setUserId(baseRequestDTO.getUserId());
        bo.setAppId(baseRequestDTO.getAppId());

        bo.setActivityCode(baseRequestDTO.getActivityCode());
        bo.setCouponCode(baseRequestDTO.getCouponCode());
        bo.setCouponCodes(baseRequestDTO.getCouponCodes());
        bo.setSendGoods(baseRequestDTO.getSendGoods());

        bo.setDiscountResultBO(discountResultBO);

        return calculationSharingAdapter.convert2CalCostBO(bo, false);
    }

    @Override
    public CalCostBO getDiscountResultAfter(ListCartGoodsBO baseRequestDTO, DiscountResultBO calCostBO, CalCostBO commonSetMessageBO) {
        return commonSetMessageBO;
    }

    @Override
    public SetMessageBO customDistribute(ListCartGoodsBO baseRequestDTO, DistributeBO calCostBO, SetMessageBO commonSetMessageBO) {

        CouponPromotionVO couponPromotionVO = couponAdapter.getCouponPromotionVO(baseRequestDTO);

        DistributeAdapterBO bo = new DistributeAdapterBO();
        bo.setCouponCode(baseRequestDTO.getCouponCode());
        bo.setPartnerId(baseRequestDTO.getPartnerId());
        bo.setShopId(baseRequestDTO.getShopId());
        bo.setUserId(baseRequestDTO.getUserId());
        distributeAdapter.adapter(calCostBO, commonSetMessageBO, bo, couponPromotionVO, 2);

        return commonSetMessageBO;

    }

    @Override
    public AddGoodsToShoppingCartBO checkCustomBusinessRules(ListCartGoodsBO baseRequestDTO, CheckBussinessRulesBO checkBussinessRulesBO, AddGoodsToShoppingCartBO addGoodsToShoppingCartBO) {
        CheckAdapterBO bo = new CheckAdapterBO();
        bo.setMenuType(baseRequestDTO.getMenuType());
        bo.setPartnerId(baseRequestDTO.getPartnerId());
        bo.setShopId(baseRequestDTO.getShopId());
        bo.setCouponCode(baseRequestDTO.getCouponCode());
        bo.setUserId(baseRequestDTO.getUserId());
        bo.setOrderType(baseRequestDTO.getOrderType());
        checkAdapter.adapter(checkBussinessRulesBO, addGoodsToShoppingCartBO, bo);

        return addGoodsToShoppingCartBO;
    }

    private ValidateShopProductRequestBO getValidateShopProductRequestBO(ProductBO product, ListCartGoodsBO baseRequestDTO) {
        ValidateShopProductRequestBO request = new ValidateShopProductRequestBO();
        request.setChannel(baseRequestDTO.getMenuType());
        request.setPartnerId(baseRequestDTO.getPartnerId());
        request.setStoreId(baseRequestDTO.getShopId());
        List<ValidateShopProductType> productTypeList = new ArrayList<>();
        ValidateShopProductType productType = new ValidateShopProductType();

        productType.setAttributeList(null);
        productType.setComboProductTypeList(null);
        productType.setMemberDiscount(null);
        productType.setPrice(product.getFinalPrice().intValue());
        productType.setProductGroupTypeList(null);
        productType.setSpuId(product.getSpuId());
        productType.setUuid(UUID.randomUUID().toString());
        productType.setValidateAttribute(0);
        productType.setValidatePrice(0);
        productType.setValidateStatuses(null);

        productTypeList.add(productType);
        request.setProductTypeList(productTypeList);
        return  request;

    }

    /**
     * 公共DTO头
     *
     * @param partnerId
     * @param storeId
     * @param userId
     * @param appId
     * @param orderType
     * @return
     */
    private GetCalculationDiscountBO commonSharingDto(String partnerId, String storeId, String userId, String appId, Integer orderType) {
        GetCalculationDiscountBO calculationSharingDiscountRequestDto = new GetCalculationDiscountBO();

        calculationSharingDiscountRequestDto.setPartnerCode(partnerId);
        calculationSharingDiscountRequestDto.setStoreId(storeId);
        calculationSharingDiscountRequestDto.setIsShowGoodsActivity(1);
        calculationSharingDiscountRequestDto.setUserId(userId);
        calculationSharingDiscountRequestDto.setAppId(appId);
        calculationSharingDiscountRequestDto.setVer(1);
        calculationSharingDiscountRequestDto.setSelectActivityList(new ArrayList<>());
        ActivityChannelEnum activityChannelEnum = PropertyConvertUtil.orderTypeConvert2ActivityChannel(orderType);
        if (!Objects.isNull(activityChannelEnum)) {
            calculationSharingDiscountRequestDto.setChannel(activityChannelEnum.getCode());
        }

        //==========================  购物车查询特有逻辑  =================================
        // 到店自取包装费设为null,外卖要计算包装费，flag为1表示去结算
        // 兼容老版本判断null
        if (Objects.equals(orderType, CreateOrderType.COLLECT_GOODS.getCode())) {
            calculationSharingDiscountRequestDto.setProductChannel(BusinessTypeEnum.SAAS_PICKUP.getCode());
        } else if (Objects.equals(orderType, CreateOrderType.TAKE_OUT.getCode())) {
            calculationSharingDiscountRequestDto.setProductChannel(BusinessTypeEnum.SAAS_DELIVERY.getCode());
        }
        return calculationSharingDiscountRequestDto;
    }

    /**
     * 实物商品
     * @param calculationDiscountGoodsList
     * @param cartGoods
     */
    private void setCommonDiscountGoods(List<GetCalculationDiscountBO.CalculationDiscountGoods> calculationDiscountGoodsList
            , CartGoods cartGoods) {

        GetCalculationDiscountBO.CalculationDiscountGoods calculationDiscountGoods = new GetCalculationDiscountBO.CalculationDiscountGoods();
        calculationDiscountGoods.setGoodsId(cartGoods.getGoodsId());
        calculationDiscountGoods.setCartGoodsUid(cartGoods.getCartGoodsUid());
        calculationDiscountGoods.setGoodsQuantity(cartGoods.getQty());
        //if (cartGoods.getGoodsType().equals(GoodsTypeEnum.SET_MEAL_GOODS))
        if (CollectionUtils.isNotEmpty(cartGoods.getProductGroupList()) || CollectionUtils.isNotEmpty(cartGoods.getProductComboList())) {
            calculationDiscountGoods.setOriginalPrice(cartGoods.getFinalPrice()!=null ? cartGoods.getFinalPrice() : cartGoods.getOriginalPrice());
        }
        else {
            calculationDiscountGoods.setOriginalPrice(cartGoods.getOriginalPrice());
        }
        calculationDiscountGoods.setMemberDiscount(cartGoods.getMemberDiscount());
        calculationDiscountGoods.setSpuId(cartGoods.getSpuId());
        //商品加料
        if (CollectionUtils.isNotEmpty(cartGoods.getProductMaterialList())) {
            ArrayList<GetCalculationDiscountBO.CalculationDiscountGoods.Material> materials = new ArrayList<>();
            for (CartGoods.MaterialGoods materialGoods : cartGoods.getProductMaterialList()) {
                GetCalculationDiscountBO.CalculationDiscountGoods.Material material = new GetCalculationDiscountBO.CalculationDiscountGoods.Material();
                material.setType(1);
                material.setGoodsId(materialGoods.getSpuId());
                material.setGoodsQuantity(1);
                material.setOriginalPrice(materialGoods.getFinalPrice());
                materials.add(material);
            }
            calculationDiscountGoods.setSmallMaterial(materials);
        }
        //商品组或是套餐或是固定搭配
        if (CollectionUtils.isNotEmpty(cartGoods.getProductComboList())) {
            ArrayList<GetCalculationDiscountBO.CalculationDiscountGoods.GroupCombox> groupBoxes = new ArrayList<>();
            for (CartGoods.ComboxGoods boxes : cartGoods.getProductComboList()) {
                GetCalculationDiscountBO.CalculationDiscountGoods.GroupCombox combo = new GetCalculationDiscountBO.CalculationDiscountGoods.GroupCombox();
                combo.setGoodsId(boxes.getGoodsId());
                combo.setGoodsQuantity(boxes.getQty());
                combo.setOriginalPrice(boxes.getOriginalPrice().intValue());
                groupBoxes.add(combo);
            }
            calculationDiscountGoods.setMeal(true);
            calculationDiscountGoods.setGroupCombox(groupBoxes);
            calculationDiscountGoods.setOriginalPrice(cartGoods.getFinalPrice());
        }

        //可选搭配
        if (CollectionUtils.isNotEmpty(cartGoods.getProductGroupList())) {
            ArrayList<GetCalculationDiscountBO.CalculationDiscountGoods.Material> groups = new ArrayList<>();
            for (CartGoods.ComboxGoods group : cartGoods.getProductGroupList()) {
                GetCalculationDiscountBO.CalculationDiscountGoods.Material material = new GetCalculationDiscountBO.CalculationDiscountGoods.Material();
                material.setType(2);
                material.setGoodsId(group.getGoodsId());
                material.setGoodsQuantity(group.getQty());
                material.setOriginalPrice(group.getFinalPrice());
                groups.add(material);
            }
            calculationDiscountGoods.setSmallMaterial(groups);
        }
        calculationDiscountGoodsList.add(calculationDiscountGoods);
    }

    private void setSpqDiscountGoods(List<GetCalculationDiscountBO.CalculationDiscountGoods> calculationDiscountGoodsList
            , CartGoods cartGoods
            , String goodsId
            , Long originalPrice
            ,String couponCode) {
        GetCalculationDiscountBO.CalculationDiscountGoods calculationDiscountGoods = new GetCalculationDiscountBO.CalculationDiscountGoods();
        calculationDiscountGoods.setGoodsId(goodsId);
        calculationDiscountGoods.setCartGoodsUid(cartGoods.getCartGoodsUid());
        calculationDiscountGoods.setGoodsQuantity(cartGoods.getQty());
        calculationDiscountGoods.setOriginalPrice(originalPrice);
        calculationDiscountGoods.setMemberDiscount(100);
        calculationDiscountGoods.setCouponCode(couponCode);
        this.setCalculationDiscountGoods(calculationDiscountGoodsList,calculationDiscountGoods);
    }

    /**
     * 需要促销计算的商品
     * @param calculationDiscountGoodsList
     * @param calculationDiscountGoods
     */
    private void setCalculationDiscountGoods(List<GetCalculationDiscountBO.CalculationDiscountGoods> calculationDiscountGoodsList
            ,GetCalculationDiscountBO.CalculationDiscountGoods calculationDiscountGoods) {
        int index = 0;
        //当商品已经存在时，需要累加数量
        if ((index = calculationDiscountGoodsList.indexOf(calculationDiscountGoods))>=0) {
            GetCalculationDiscountBO.CalculationDiscountGoods old = calculationDiscountGoodsList.get(index);
            calculationDiscountGoodsList.get(index).setGoodsQuantity(old.getGoodsQuantity()+calculationDiscountGoods.getGoodsQuantity());
        }
        else {
            calculationDiscountGoodsList.add(calculationDiscountGoods);
        }

    }

    public ActivityClassifyCouponBean createEmptyActivityCouponBean() {
        ActivityClassifyCouponBean activityClassifyCouponBean = new ActivityClassifyCouponBean();
        activityClassifyCouponBean.setCouponNum(0);
        activityClassifyCouponBean.setDisableCouponNum(0);
        activityClassifyCouponBean.setUsableCouponNum(0);
        activityClassifyCouponBean.setDisableCoupons(Lists.newArrayList());
        activityClassifyCouponBean.setUsableCoupons(Lists.newArrayList());
        return activityClassifyCouponBean;
    }

}
