package cn.freemud.service.impl;

import ch.qos.logback.classic.Level;
import cn.freemud.adapter.ShoppingCartConvertAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.entities.dto.GetCouponDetailResponseDto;
import cn.freemud.entities.dto.ProductBaseResponse;
import cn.freemud.entities.dto.RequiredProductRequest;
import cn.freemud.entities.dto.coupon.Active;
import cn.freemud.entities.dto.product.*;
import cn.freemud.entities.vo.CartGoods;
import cn.freemud.entities.vo.GetMemberCouponRequestVo;
import cn.freemud.entities.vo.ShoppingCartGoodsResponseVo;
import cn.freemud.service.ProductService;
import cn.freemud.service.thirdparty.ProductClient;
import com.freemud.sdk.api.assortment.shoppingcart.constant.*;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CartGoodsStates;
import com.freemud.sdk.api.assortment.shoppingcart.util.CartResponseUtil;
import com.freemud.sdk.api.assortment.shoppingcart.util.PropertyConvertUtil;
import com.freemud.sdk.api.assortment.shoppingcart.util.ShoppingSdkLogUtil;
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.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: null.java
 * @Package
 * @Description: (用一句话描述该文件做什么)
 * @author: 蓝胖子(Hector)
 * @date: 2019-11-20
 * @Copyright: 2018 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目的
 */

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductClient productClient;

    @Autowired
    private CouponServiceImpl couponService;

    @Autowired
    private ShoppingCartConvertAdapter shoppingCartConvertAdapter;

    @Override
    public boolean hasRequiredProducts(String partnerId, String storeId, List<CartGoods> cartGoodsList,String menuType) {
        RequiredProductRequest request = RequiredProductRequest.builder().channel(menuType).partnerId(partnerId).shopId(storeId).build();
        ProductBaseResponse<List<String>> requiredProductList = productClient.getRequiredProductList(request);
        if (null != requiredProductList && ResponseCodeConstant.RESPONSE_SUCCESS.equals(requiredProductList.getErrcode()) &&
                !CollectionUtils.isEmpty(requiredProductList.getData())) {
            List<String> spuIds = cartGoodsList.stream().map(good -> good.getSpuId()).collect(Collectors.toList());
            // 两个集合只要没有交集，就返回true
            if (CollectionUtils.isEmpty(requiredProductList.getData().stream().filter(item -> spuIds.contains(item)).collect(Collectors.toList()))) {
                return true;
            }
        }
        return false;
    }


    /**
     * 校验商品
     */
    public BaseResponse<CheckCartRequest> checkAllCartGoodsNew(CheckCartRequest checkCartRequest) {
        try {
            ValidateShopProductRequest validateShopProductRequest = shoppingCartConvertAdapter.getValidateShopProductRequest(checkCartRequest);
            if(CollectionUtils.isEmpty(validateShopProductRequest.getProductTypeList())){
                return CartResponseUtil.success(checkCartRequest);
            }
            ProductBaseResponse<ValiadShopProductResponse>  valiadResponse = productClient.validateShopProduct(validateShopProductRequest);
            if (valiadResponse == null || !Objects.equals(ResponseCodeConstant.RESPONSE_SUCCESS,valiadResponse.getErrcode()) || valiadResponse.getData()==null) {
                checkCartRequest.getCartGoodsList().clear();
                checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
                return CartResponseUtil.error(valiadResponse.getErrmsg(),checkCartRequest);
            }
            ValiadShopProductResponse valiadResult = valiadResponse.getData();
            if (CollectionUtils.isEmpty(valiadResult.getSuccessList())) {
                checkCartRequest.getCartGoodsList().clear();
                checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
                return CartResponseUtil.success(checkCartRequest);
            }
            Map<String, ValiadShopProductResult> successMap = valiadResult.getSuccessList().stream().collect(Collectors.toMap(ValiadShopProductResult::getUuid, Function.identity(), (k1, k2) -> k1));
            //非法商品（商品是否存在、商品是否处于上架状态）自动移除，返回前端提示
            boolean hasChange = false;
            for (CartGoods cartGoods :checkCartRequest.getCartGoodsList()) {
                // 当goodsId为空或商品是商品券时直接跳过
                if (StringUtils.isEmpty(cartGoods.getGoodsId()) || Objects.equals(cartGoods.getGoodsType(), GoodsTypeEnum.COUPON_GOODS.getGoodsType())
                        || Objects.equals(cartGoods.getGoodsType(), GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType())
                        || Objects.equals(cartGoods.getGoodsType(), GoodsTypeEnum.BUY_M_SEND_N_COUPON.getGoodsType())) {
                    continue;
                }
                if (!successMap.containsKey(cartGoods.getCartGoodsUid())){
                    hasChange = true;
                    cartGoods.setCartGoodsUid(null);
                    checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                    checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
                }
            }
            if (hasChange){
                setToastMsgIfNotExist(checkCartRequest.getShoppingCartGoodsResponseVo(), ShoppingCartConstant.SHOPPING_CART_GOODS_CHANGE);
                checkCartRequest.getCartGoodsList().removeIf(k ->  StringUtils.isEmpty(k.getCartGoodsUid()));
            }
            // Todo : 验证的商品信息
            List<ProductTypeBeanDTO> productList = valiadResult.getSuccessList().stream().map(ValiadShopProductResult::getProductType).collect(Collectors.toList());
            CartGoodsStates cartGoodsStates = new CartGoodsStates();
            for (CartGoods cartGoods : checkCartRequest.getCartGoodsList()) {
                // 当goodsId为空或商品是商品券时直接跳过
                if (StringUtils.isEmpty(cartGoods.getGoodsId()) || Objects.equals(cartGoods.getGoodsType(), GoodsTypeEnum.COUPON_GOODS.getGoodsType())
                        || Objects.equals(cartGoods.getGoodsType(), GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType())
                        || Objects.equals(cartGoods.getGoodsType(), GoodsTypeEnum.BUY_M_SEND_N_COUPON.getGoodsType())) {
                    continue;
                }
                // fisherman 添加原有商品类型
                shoppingCartConvertAdapter.updateCartGoodsInfoNew(cartGoods, productList);
            }
            //校验商品券是否有当前点餐方式
            cartGoodsStates = updateSpqCartGoodsInfo(checkCartRequest.getCartGoodsList(), checkCartRequest.getOrderWay(), checkCartRequest.getPartnerId(), checkCartRequest.getTrackingNo(), cartGoodsStates
                    , checkCartRequest.getStoreId());

            // 点餐方式改变商品券发生变动
            if (cartGoodsStates != null && cartGoodsStates.isOrderWayFlag()) {
                setToastMsgIfNotExist(checkCartRequest.getShoppingCartGoodsResponseVo(), ShoppingCartConstant.ORDER_WAY_CHANGE);
            }
            //若商品详情赋值有异常，直接移除购物车
            if (checkCartRequest.getCartGoodsList().stream().anyMatch(cart -> StringUtils.isEmpty(cart.getCartGoodsUid()))) {
                checkCartRequest.getCartGoodsList().removeIf(k -> StringUtils.isEmpty(k.getCartGoodsUid()));
                checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
            }
            //todo 小料
            if (checkCartRequest.getCartGoodsList().stream().anyMatch(cart -> cart.getGoodsType().equals(GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType()))) {
                checkCartRequest.getCartGoodsList().removeIf(k -> k.getGoodsType().equals(GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType()));
                checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_MATERIAL_ERROR);
            }
            return CartResponseUtil.success(checkCartRequest);
        } catch (Exception e) {
            checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
            checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
            return CartResponseUtil.error(e.getMessage(),checkCartRequest);
        }
    }

    /**
     * 当ToastMsg为空时才赋值
     *
     * @param shoppingCartGoodsResponseVo
     * @param message
     */
    private void setToastMsgIfNotExist(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, String message) {
        if (StringUtils.isEmpty(shoppingCartGoodsResponseVo.getToastMsg())) {
            shoppingCartGoodsResponseVo.setToastMsg(message);
        }
    }

    /**
     * 根据点餐方式、校验商品券是否满足
     *
     * @param cartGoodsList
     * @param orderWay
     * @return
     */
    private CartGoodsStates updateSpqCartGoodsInfo(List<CartGoods> cartGoodsList, Integer orderWay, String partnerId, String trackingNo, CartGoodsStates goodsStates, String storeId) {
        //获取所有商品券cartGoodsUid=sqp+code
        List<String> couponIds = cartGoodsList.parallelStream()
                .filter(k ->StringUtils.isNotEmpty(k.getCartGoodsUid())&& k.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX)).map(CartGoods::getSpuId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(couponIds)) {
            couponIds = cartGoodsList.parallelStream()
                    .filter(k ->StringUtils.isNotBlank(k.getCouponCode())).map(CartGoods::getCouponCode).collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(couponIds)) {
            return goodsStates;
        }
        List<GetCouponDetailResponseDto.Details> detailVOList = getCouponsDetail(partnerId, storeId, couponIds, trackingNo);
        if (CollectionUtils.isEmpty(detailVOList)) {
            return goodsStates;
        }

        Map<String, GetCouponDetailResponseDto.Details> detailsMap;
        List<String> activityCode;
        Map<String, Boolean> couponOrderWayMap;

        detailsMap = detailVOList.stream().collect(Collectors.toMap(p -> p.getCode(), (p) -> p, (v1, v2) ->v1));
        activityCode = detailVOList.stream().map(p -> p.getActiveCode()).collect(Collectors.toList());
        couponOrderWayMap = getCouponOrderWay(partnerId, activityCode, orderWay, trackingNo);
        //遍历商品券是否有当前点餐方式点餐
        boolean orderWayFlag = false;
        if (CollectionUtils.isNotEmpty(cartGoodsList)) {
            orderWayFlag = checkProductOrderWay(cartGoodsList, detailsMap, couponOrderWayMap);
        }
        if (orderWayFlag) {
            goodsStates.setOrderWayFlag(true);
            cartGoodsList.removeIf(k -> k.getCartGoodsUid() == null);
        }
        return goodsStates;
    }

    /**
     * 查询券详情
     *
     * @param partnerId
     * @param codes
     * @param trackingNo
     * @return
     */
    private List<GetCouponDetailResponseDto.Details> getCouponsDetail(String partnerId, String storeId, List<String> codes, String trackingNo) {

         String couponCode = String.join(",", codes);
        //TODO 查询券详情券是否存在
        GetMemberCouponRequestVo requestVo = new GetMemberCouponRequestVo();
        requestVo.setPartnerId(partnerId);
        requestVo.setCouponCode(couponCode);
        requestVo.setStoreId(storeId);
        GetCouponDetailResponseDto couponDetailResponseDto = couponService.getMemberCoupon(requestVo);
        if (couponDetailResponseDto == null || !couponDetailResponseDto.getResult().equals(ResponseCodeConstant.RESPONSE_SUCCESS_1) || CollectionUtils.isEmpty(couponDetailResponseDto.getDetails())) {
            return null;
        }
        return couponDetailResponseDto.getDetails();
    }

    /**
     * 校验点餐方式
     * key = 活动code , value = 返回是否匹配点餐方式
     *
     * @param partnerId
     * @param activityCodes
     * @param orderTye
     * @param trackingNo
     * @return
     */
    public Map<String, Boolean> getCouponOrderWay(String partnerId, List<String> activityCodes, Integer orderTye, String trackingNo) {
        try {
            List<Active> activeDetailVOList = couponService.batchQueryActivityInfo(partnerId, activityCodes, trackingNo);
            if (CollectionUtils.isEmpty(activeDetailVOList)) {
                return null;
            }
            Map<String, Boolean> result = new HashMap<>();
            ActivityChannelEnum activityChannelEnum = PropertyConvertUtil.orderTypeConvert2ActivityChannel(orderTye);
            activeDetailVOList.forEach(active -> {
                if (Objects.isNull(active.getRedeemChannel())) {
                    result.put(active.getActiveCode(), true);
                } else {
                    result.put(active.getActiveCode(), Arrays.stream(active.getRedeemChannel().split(",")).anyMatch(Predicate.isEqual(activityChannelEnum.getCode())));
                }
            });

            return result;
        } catch (Exception e) {
            ShoppingSdkLogUtil.printErrorLog("assortment-shoppingcart-sdk", trackingNo, e.getMessage(), "getCouponOrderWay", null, e, Level.ERROR);
            return null;
        }

    }

    /**
     * 商品券是否有当前点餐方式点餐
     *
     * @param cartGoodsList
     * @param detailsMap
     * @param couponOrderWayMap
     * @return
     */
    private boolean checkProductOrderWay(List<CartGoods> cartGoodsList, Map<String, GetCouponDetailResponseDto.Details> detailsMap, Map<String, Boolean> couponOrderWayMap) {
        boolean orderWayFlag = false;
        // TODO: 21-11-5  判断券商品待删除
        List<CartGoods> cartGoodsByProduct = cartGoodsList.stream()
                .filter(cartGoods -> cartGoods.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(cartGoodsByProduct)){
            cartGoodsByProduct = cartGoodsList.stream()
                    .filter(cartGoods -> StringUtils.isNotBlank(cartGoods.getCouponCode()))
                    .collect(Collectors.toList());
        }
        for (CartGoods cartGoods : cartGoodsByProduct) {
            GetCouponDetailResponseDto.Details detail = detailsMap.get(cartGoods.getCouponCode());
            String activeCode = detail != null ? detail.getActiveCode() : "";
            if (couponOrderWayMap == null || couponOrderWayMap.isEmpty() || !couponOrderWayMap.get(activeCode)) {
                orderWayFlag = true;
                cartGoods.setCartGoodsUid(null);
            }
        }

        return orderWayFlag;
    }

}
