package com.freemud.sdk.api.assortment.shoppingcart.adapter;

import com.freemud.application.sdk.api.productcenter.domain.ProductBeanDTO;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CommonsConstant;
import com.freemud.sdk.api.assortment.shoppingcart.constant.GoodsTypeEnum;
import com.freemud.sdk.api.assortment.shoppingcart.constant.ProductStatus;
import com.freemud.sdk.api.assortment.shoppingcart.constant.ProductType;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CartGoods;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CartGoodsStates;
import com.freemud.sdk.api.assortment.shoppingcart.request.CheckCartRequest;
import com.freemud.sdk.api.assortment.shoppingcart.request.GetProductInfoRequest;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

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

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: ShoppingCartAdapter
 * @Package com.freemud.sdk.api.assortment.shoppingcart.adapter
 * @Description:
 * @author: yuhao.chi
 * @date: 2019/4/10 15:02
 * @Copyright: 2019 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目的
 */
@Component
public class ShoppingCartAdapter {
    private static final String ATTRIBUTEID = "attributeId";
    private static final String ATTRIBUTENAME = "attributeName";

    public GetProductInfoRequest convertGetProductInfoRequest(String partnerId, String storeId, List<String> goodsIds, String trackingNo) {
        GetProductInfoRequest request = new GetProductInfoRequest();
        request.setPartnerId(partnerId);
        request.setStoreId(storeId);
        request.setGoodsIds(goodsIds);
        request.setTrackingNo(trackingNo);
        return request;
    }

    public GetProductInfoRequest convertGetProductInfoRequest(CheckCartRequest checkCartRequest) {
        //获取goodsId集合，包含套餐内的固定商品和可选商品
        List<List<CartGoods.ComboxGoods>> productGroupLists = checkCartRequest.getCartGoodsList().stream().filter(goods -> CollectionUtils.isNotEmpty(goods.getProductGroupList())).map(CartGoods::getProductGroupList).collect(Collectors.toList());
        List<List<CartGoods.ComboxGoods>> productComboLists = checkCartRequest.getCartGoodsList().stream().filter(goods -> CollectionUtils.isNotEmpty(goods.getProductComboList())).map(CartGoods::getProductComboList).collect(Collectors.toList());
        List<String> goodsIds = checkCartRequest.getCartGoodsList().stream().filter(cartGoods -> !cartGoods.getCartGoodsUid().startsWith("spq")).map(CartGoods::getGoodsId).collect(Collectors.toList());
        goodsIds.addAll(checkCartRequest.getCartGoodsList().stream().filter(t -> !t.getCartGoodsUid().startsWith("spq") && StringUtils.isNotEmpty(t.getSpuId())).map(CartGoods::getSpuId).collect(Collectors.toList()));
        for (List<CartGoods.ComboxGoods> productGroupList : productGroupLists) {
            goodsIds.addAll(productGroupList.stream().map(CartGoods.ComboxGoods::getGoodsId).collect(Collectors.toList()));
        }
        for (List<CartGoods.ComboxGoods> productComboList : productComboLists) {
            goodsIds.addAll(productComboList.stream().map(CartGoods.ComboxGoods::getGoodsId).collect(Collectors.toList()));
        }
        //
        GetProductInfoRequest request = new GetProductInfoRequest();
        request.setPartnerId(checkCartRequest.getPartnerId());
        request.setStoreId(checkCartRequest.getStoreId());
        request.setGoodsIds(goodsIds.stream().distinct().collect(Collectors.toList()));
        return request;
    }


    /**
     * 更新当前购物车商品行信息
     *
     * @param cartGoods       当前购物车商品行
     * @param productBeans    购物车中所有的productId对应的商品详情
     * @param cartGoodsStates 购物车状态
     */
    public void updateCartGoodsInfo(CartGoods cartGoods, List<ProductBeanDTO> productBeans, CartGoodsStates cartGoodsStates, List<String> invalidGoodsIdList) {
        Optional<ProductBeanDTO> firstProduct = productBeans.stream().filter(p -> ObjectUtils.equals(p.getPid(), cartGoods.getGoodsId())).findFirst();
        if (!firstProduct.isPresent()) {
            // 标记非法商品
            invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            return;
        }
        ProductBeanDTO productBean = firstProduct.get();
        // 如果是sku普通商品，则商品属相取sku对应的spu的属性
        List<ProductBeanDTO.ProductAttributeGroupListBean> productAttributeGroupList = productBean.getProductAttributeGroupList();
        ProductBeanDTO spuProduct = productBean;
        if (ObjectUtils.equals(GoodsTypeEnum.SKU_GOODS.getGoodsType(), cartGoods.getGoodsType()) || StringUtils.isNotEmpty(cartGoods.getSkuId())) {
            Optional<ProductBeanDTO> spuProduct1 = productBeans.stream().filter(p -> ObjectUtils.equals(p.getPid(), cartGoods.getSpuId())).findFirst();
            if (!spuProduct1.isPresent()) {
                // 标记非法商品
                invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                return;
            }
            spuProduct = spuProduct1.get();
            productAttributeGroupList = spuProduct1.get().getProductAttributeGroupList();
        }
        // 商品非上架状态
        if (ObjectUtils.notEqual(ProductStatus.SALEON.getCode(), productBean.getStatus()) || ObjectUtils.notEqual(ProductStatus.SALEON.getCode(), spuProduct.getStatus())) {
            // 标记非法商品
            invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            return;
        }
        Map<String, String> attributes = getAttributes(cartGoods, cartGoods.getExtra(), productAttributeGroupList, invalidGoodsIdList);
        cartGoods.setName(spuProduct.getName());
        cartGoods.setSpuName(spuProduct.getName());
        cartGoods.setSkuName(productBean.getName());
        cartGoods.setSpecProductId(attributes.get(ATTRIBUTEID));

        String skuSpecName = "";
        if (CollectionUtils.isNotEmpty(productBean.getSkuSpecValues())) {
            List<String> skuSpecValus = productBean.getSkuSpecValues().stream().map(p -> p.getSpecValue()).collect(Collectors.toList());
            skuSpecName = StringUtils.join(skuSpecValus, "/");
        }
        String attributeName = attributes.get(ATTRIBUTENAME) == null ? "" : attributes.get(ATTRIBUTENAME);
        cartGoods.setSubName(StringUtils.isNotEmpty(skuSpecName) && StringUtils.isNotEmpty(attributeName) ?
                skuSpecName + "/" + attributeName : skuSpecName + attributeName);


        cartGoods.setPic(StringUtils.isBlank(productBean.getPicture()) ? spuProduct.getPicture() : productBean.getPicture());
        cartGoods.setPackPrice(productBean.getPackPrice());
        cartGoods.setStockLimit(ObjectUtils.equals(1, productBean.getStockLimit()));
        cartGoods.setCustomerCode(productBean.getCustomerCode());
        // 如果是套餐商品，更新套餐内固定商品&可选商品的详细信息
        boolean isSetMealProduct = ObjectUtils.equals(ProductType.SetMeal.getCode(), productBean.getType()) || ObjectUtils.equals(ProductType.IncreasedPackage.getCode(), productBean.getType());
        if (isSetMealProduct) {
            if (CollectionUtils.isNotEmpty(cartGoods.getProductComboList())) {
                //check 套餐内固定商品是否有变化，若有变化移除购物车
                if (checkComboProductChange(cartGoods.getProductComboList(), productBean, cartGoods, invalidGoodsIdList)) {
                    return;
                }
                for (CartGoods.ComboxGoods productCombo : cartGoods.getProductComboList()) {
                    //如果套餐内固定商品移除，默认移除当前商品行
                    boolean isExist = productBean.getProductComboList().stream().anyMatch(p -> ObjectUtils.equals(productCombo.getGoodsId(), p.getProductId()));
                    if (!isExist) {
                        // 标记非法商品
                        invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                        return;
                    }
                    if (!updateComboxGoodsInfo(cartGoods, productCombo, firstProduct.get(), productBeans, cartGoodsStates, invalidGoodsIdList)) {
                        return;
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(cartGoods.getProductGroupList())) {
                List<String> productGroupIdList = new ArrayList<>();
                productBean.getProductGroupList().stream().map(t -> t.getGroupDetail()).forEach(t -> t.stream().forEach(group -> productGroupIdList.add(group.getProductId())));
                for (CartGoods.ComboxGoods productGroup : cartGoods.getProductGroupList()) {
                    //如果套餐内可选商品移除，默认移除当前商品行
                    boolean isExist = productGroupIdList.stream().anyMatch(p -> ObjectUtils.equals(productGroup.getGoodsId(), p));
                    if (!isExist) {
                        // 标记非法商品
                        invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                        return;
                    }
                    if (!updateComboxGoodsInfo(cartGoods, productGroup, firstProduct.get(), productBeans, cartGoodsStates, invalidGoodsIdList)) {
                        return;
                    }
                }
            }
        }
        //更新当前商品行价格，check价格是否变更
        Long newOrigOriginalPrice = 0L;
        if (isSetMealProduct) {
            //如果是套餐，则当前商品行价格为：固定套餐价格* 数量+可选商品加价 价格
            Map<String, Integer> productOriginalPrices = new HashMap<>();
            Map<String, Integer> productMarkUpPrices = new HashMap<>();
            productBean.getProductGroupList().stream().map(t -> t.getGroupDetail()).forEach(t -> productMarkUpPrices.putAll(t.stream().collect(Collectors.toMap(ProductBeanDTO.ProductGroupType.GroupDetailType::getProductId, ProductBeanDTO.ProductGroupType.GroupDetailType::getMarkUpPrice))));
            productBean.getProductGroupList().stream().map(t -> t.getGroupDetail()).forEach(t -> productOriginalPrices.putAll(t.stream().collect(Collectors.toMap(ProductBeanDTO.ProductGroupType.GroupDetailType::getProductId, ProductBeanDTO.ProductGroupType.GroupDetailType::getProductFinalPrice))));
            if (CollectionUtils.isNotEmpty(cartGoods.getProductGroupList())) {
                for (CartGoods.ComboxGoods groupProduct : cartGoods.getProductGroupList()) {
                    Integer originalPrice = productOriginalPrices.get(groupProduct.getGoodsId()) == null ? 0 : productOriginalPrices.get(groupProduct.getGoodsId());
                    newOrigOriginalPrice += originalPrice * groupProduct.getQty();
                }
            }
            newOrigOriginalPrice += productBean.getProductComboList().stream().mapToInt(t -> t.getQuantity() * t.getFinalPrice()).sum();
        } else {
            newOrigOriginalPrice = productBean.getFinalPrice();
        }
        Long oldOrigOriginalPrice = cartGoods.getOriginalPrice();
        if (null != oldOrigOriginalPrice && !Objects.equals(newOrigOriginalPrice, oldOrigOriginalPrice)) {
            cartGoodsStates.setPriceChanged(true);
        }
        cartGoods.setOriginalPrice(newOrigOriginalPrice);
        cartGoods.setOriginalAmount(newOrigOriginalPrice*cartGoods.getQty());
        cartGoods.setAmount(newOrigOriginalPrice*cartGoods.getQty());
        //咨询商品服务，套餐售价取originalPrice
        cartGoods.setFinalPrice(isSetMealProduct?productBean.getOriginalPrice(): productBean.getFinalPrice());
        cartGoods.setUnit(productBean.getUnit());
        cartGoods.setWeightType(CommonsConstant.WEIGHT_PRODUCT.equals(productBean.getWeightType()));
    }

    private boolean updateComboxGoodsInfo(CartGoods cartGoods, CartGoods.ComboxGoods comboxGoods, ProductBeanDTO parentProductBean, List<ProductBeanDTO> productBeans, CartGoodsStates cartGoodsStates, List<String> invalidGoodsIdList) {
        // 可选商品详情
        Optional<ProductBeanDTO> firstProduct = productBeans.stream().filter(p -> ObjectUtils.equals(p.getPid(), comboxGoods.getGoodsId())).findFirst();
        if (!firstProduct.isPresent()) {
            invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            return false;
        }
        ProductBeanDTO productBean = firstProduct.get();
        // 商品非上架状态
        if (ObjectUtils.notEqual(ProductStatus.SALEON.getCode(), productBean.getStatus())) {
            // 标记非法商品
            invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            return false;
        }
        // 查找可选商品的加价价格，若无则取商品详情的FinalPrice，若有则取MarkUpPrice
        Long finalPrice = productBean.getFinalPrice();
        List<ProductBeanDTO.ProductGroupType.GroupDetailType> groupDetailList = new ArrayList<>();
        parentProductBean.getProductGroupList().forEach(group -> groupDetailList.addAll(group.getGroupDetail()));
        List<ProductBeanDTO.ProductGroupType.GroupDetailType> groupProducts = groupDetailList.stream().filter(g -> ObjectUtils.equals(comboxGoods.getGoodsId(), g.getProductId())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(groupProducts)) {
            finalPrice = groupProducts.get(0).getMarkUpPrice() == null ? 0L : groupProducts.get(0).getMarkUpPrice().longValue();
        }
        // 设置商品详情
        Map<String, String> attributes = getAttributes(cartGoods, comboxGoods.getExtra(), productBean.getProductAttributeGroupList(), invalidGoodsIdList);
        comboxGoods.setName(productBean.getName());
        comboxGoods.setSpuName(productBean.getName());
        comboxGoods.setSpecProductId(attributes.get(ATTRIBUTEID));
        comboxGoods.setSubName(attributes.get(ATTRIBUTENAME));
        // check价格是否变更
        Long newOrigOriginalPrice = productBean.getFinalPrice();
        Long oldOrigOriginalPrice = comboxGoods.getOriginalPrice();
        if (!Objects.equals(newOrigOriginalPrice, oldOrigOriginalPrice)) {
            cartGoodsStates.setPriceChanged(true);
        }
        comboxGoods.setPic(productBean.getPicture());
        comboxGoods.setPackPrice(productBean.getPackPrice());
        comboxGoods.setOriginalPrice(productBean.getFinalPrice());
        comboxGoods.setOriginalAmount(productBean.getFinalPrice()*comboxGoods.getQty());
        comboxGoods.setAmount(finalPrice*comboxGoods.getQty());
        comboxGoods.setCustomerCode(productBean.getCustomerCode());
        comboxGoods.setFinalPrice(finalPrice);
        comboxGoods.setWeightType(CommonsConstant.WEIGHT_PRODUCT.equals(productBean.getWeightType()));
        comboxGoods.setUnit(productBean.getUnit());
        return true;
    }

    private Map<String, String> getAttributes(CartGoods cartGoods, List<CartGoods.CartGoodsExtra> extra, List<ProductBeanDTO.ProductAttributeGroupListBean> attributeGroupListBeanList, List<String> invalidGoodsIdList) {
        if (CollectionUtils.isEmpty(extra) && CollectionUtils.isNotEmpty(attributeGroupListBeanList)) {
            invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            return new HashMap<>();
        }
        if (CollectionUtils.isEmpty(extra)) {
            return new HashMap<>();
        }
        // 查询到的商品信息
        List<String> allAttributes = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(attributeGroupListBeanList)) {
            for (ProductBeanDTO.ProductAttributeGroupListBean productAttributeGroupListBean : attributeGroupListBeanList) {
                List<String> attributes = productAttributeGroupListBean
                        .getAttributeValues()
                        .parallelStream()
                        .map(ProductBeanDTO.ProductAttributeGroupListBean.AttributeValueBean::getAttributeId)
                        .collect(Collectors.toList());
                allAttributes.addAll(attributes);
            }
        }
        // 购物车商品属性信息check是否非法（例如属性下架）
        for (CartGoods.CartGoodsExtra cartGoodsExtra : extra) {
            if (!allAttributes.contains(cartGoodsExtra.getAttributeId())) {
                // 标记非法商品
                invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                break;
            }
        }
        List<String> attributeIds = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeId).collect(Collectors.toList());
        List<String> attributeNames = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeName).collect(Collectors.toList());
        Map<String, String> result = new HashMap<>();
        result.put(ATTRIBUTEID, StringUtils.join(attributeIds, "/"));
        result.put(ATTRIBUTENAME, StringUtils.join(attributeNames, "/"));
        return result;
    }

    private boolean checkComboProductChange(List<CartGoods.ComboxGoods> comboxGoods, ProductBeanDTO productBean, CartGoods cartGoods, List<String> invalidGoodsIdList) {

        for (ProductBeanDTO.ProductComboType product : productBean.getProductComboList()) {
            if (!comboxGoods.stream().anyMatch(goods -> ObjectUtils.equals(product.getProductId(), goods.getGoodsId()))) {
                // 标记非法商品
                invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                return true;
            }
        }
        for (CartGoods.ComboxGoods combo : comboxGoods) {
            if (!productBean.getProductComboList().stream().anyMatch(product -> ObjectUtils.equals(combo.getGoodsId(), product.getProductId()))) {
                // 标记非法商品
                invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                return true;
            }
        }
        return false;
    }
}
