/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title: ItemServiceImpl
 * @Package cn.freemud.service.impl
 * @Description:
 * @author: liming.guo
 * @date: 2018/5/15 19:24
 * @version V1.0
 * @Copyright: 2018 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */

package cn.freemud.service.impl;

import cn.freemud.adapter.StoreItemAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.demo.entities.bo.goods.GetProductBySkuIdResponseBO;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.product.info.AttributeValueBean;
import cn.freemud.entities.dto.product.info.ProductBean;
import cn.freemud.entities.vo.CartGoods;
import cn.freemud.entities.vo.GetProductsVo;
import cn.freemud.enums.ProductInfoType;
import cn.freemud.enums.ResponseResult;
import cn.freemud.enums.YesOrNoEnum;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.ItemService;
import cn.freemud.service.thirdparty.ProductClient;
import cn.freemud.service.thirdparty.StockClient;
import cn.freemud.utils.ResponseUtil;
import cn.freemud.utils.Sha1Util;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
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.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class ItemServiceImpl implements ItemService {

    private final Integer RESPONSE_SUCCESS_CODE = 100;
    private static Gson gson = new Gson();
    @Autowired
    private ProductClient storeItemClient;
    @Autowired
    private StoreItemAdapter storeItemAdapter;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private StockClient stockClient;







    public BaseResponse<Map<String, ProductBean>> getProducts(String partnerId, String shopId, List<String> productIds, boolean reflash , String menuType) {
        Map<String, ProductBean> newProductBeanMap = Maps.newTreeMap();
        if (CollectionUtils.isEmpty(productIds)) {
            return ResponseUtil.success(newProductBeanMap);
        }
        productIds.sort(Comparator.comparing(p -> p));
        String key = "saas:productInfo:" + Sha1Util.sha1(gson.toJson(productIds));
        Map<String, ProductBean> productBeanMap = redisCache.getValue(key);
        if (!reflash && productBeanMap != null && productBeanMap.size() > 0) {
            return ResponseUtil.success(productBeanMap);
        }
        GetProductValidateDto getProductValidateDto = storeItemAdapter.convert2ProductValidateDto(partnerId, shopId, productIds);
        GetProductInfoDto getProductInfoDto = storeItemAdapter.convert2ProductInfoDto(partnerId, shopId, ProductInfoType.ALL.getCode(), productIds,menuType);
        ProductInfosDto productInfosDto = storeItemClient.listProductInfos(getProductInfoDto);
        if (!RESPONSE_SUCCESS_CODE.equals(productInfosDto.getErrcode()) || CollectionUtils.isEmpty(productInfosDto.getData().getProducts())) {
            return ResponseUtil.error(ResponseResult.STORE_ITEM_QUERY_ERROR);
        }
        List<String> productInfoIds = productInfosDto.getData().getProducts().stream()
                .map(ProductBean::getPid).collect(Collectors.toList());
        for (String productId : productIds) {
            if (!productInfoIds.contains(productId)) {
                return ResponseUtil.error(ResponseResult.STORE_ITEM_QUERY_ERROR.getCode(), "商品ID" + productId + "不存在");
            }
        }

        List<ProductBean> productInfosDtos = productInfosDto.getData().getProducts();
        newProductBeanMap = productInfosDtos.stream()
                .collect(Collectors.toMap(ProductBean::getPid, (p) -> p));
        redisCache.save(key, newProductBeanMap, 5L, TimeUnit.MINUTES);
        return ResponseUtil.success(newProductBeanMap);
    }


    /**
     * 获取商品所有属性map
     *
     * @param productBean
     * @return
     */
    public Map<String, AttributeValueBean> getAttributeValuesByProduct(ProductBean productBean) {
        Map<String, AttributeValueBean> attributeValueBeanMap = Maps.newTreeMap();
        if (productBean == null) {
            return attributeValueBeanMap;
        }
        if (CollectionUtils.isNotEmpty(productBean.getProductAttributeGroupList())) {
            productBean.getProductAttributeGroupList().forEach(productAttributeGroupListBean -> {
                if (CollectionUtils.isNotEmpty(productAttributeGroupListBean.getAttributeValues())) {
                    productAttributeGroupListBean.getAttributeValues().forEach(attributeValueBean -> {
                        if (!attributeValueBeanMap.containsKey(attributeValueBean.getAttributeId())) {
                            attributeValueBeanMap.put(attributeValueBean.getAttributeId(), attributeValueBean);
                        }
                    });
                }
            });
        }
        return attributeValueBeanMap;
    }

    /***
     *  判断属性是否在商品属性内
     */
    @Override
    public boolean hasAttributeAll(List<String> attributeIds, ProductBean productBean) {
        if (CollectionUtils.isEmpty(attributeIds)) {
            return true;
        }
        Map<String, AttributeValueBean> attributeValueBeanMap = getAttributeValuesByProduct(productBean);
        for (String attributeId : attributeIds) {
            if (!attributeValueBeanMap.containsKey(attributeId)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public Map<String, GetProductsVo> getProducts(List<String> pids, String partnerId, String storeId, String menuType) {
        Map<String, GetProductsVo> resultMap = new HashMap<>();
        if (CollectionUtils.isEmpty(pids)) {
            return resultMap;
        }
        List<String> skuIds = Lists.newArrayList();
        //查询商品详情
        GetProductInfoDto getProductInfoDto = storeItemAdapter.convert2ProductInfoDto(partnerId, storeId, ProductInfoType.ALL.getCode(), pids,menuType);
        ProductInfosDto productInfosDto = storeItemClient.listProductInfos(getProductInfoDto);
        if (ResponseCodeConstant.RESPONSE_SUCCESS.equals(productInfosDto.getErrcode())
                && productInfosDto.getData() != null
                && CollectionUtils.isNotEmpty(productInfosDto.getData().getProducts())) {
            productInfosDto.getData().getProducts().stream().forEach(productBean -> {
                //多规格获取sku信息
                GetProductsVo getProductsVo = new GetProductsVo();
                getProductsVo.setSkuId(productBean.getPid());
                getProductsVo.setSkuName(productBean.getName());
                String picture = CollectionUtils.isNotEmpty(productBean.getProductPictureList())
                        ? productBean.getProductPictureList().get(0).getUrl() : null;
                getProductsVo.setSpuId(productBean.getPid());
                getProductsVo.setSpuName(productBean.getName());
                getProductsVo.setSpuPicture(picture);
                getProductsVo.setOriginalPrice(productBean.getOriginalPrice());
                getProductsVo.setFinalPrice(productBean.getFinalPrice());
                getProductsVo.setProductAttributeGroupList(productBean.getProductAttributeGroupList());
                getProductsVo.setStatus(productBean.getStatus());
                getProductsVo.setStock(productBean.getStock());
                getProductsVo.setStockLimit(productBean.getStockLimit());
                getProductsVo.setCustomerCode(productBean.getCustomerCode());
                getProductsVo.setCategory(productBean.getCategory());
                getProductsVo.setCategoryName(productBean.getCategoryName());
                getProductsVo.setProductBindingCouponTypes(productBean.getProductBindingCouponTypes());
                resultMap.put(productBean.getPid(), getProductsVo);
                getProductsVo.setType(productBean.getType());
                // 规格ID 剔除单品
                if (Objects.equals(productBean.getIsSkuProduct(), YesOrNoEnum.YES.getCode())) {
                    getProductsVo.setType(10);
                    skuIds.add(productBean.getPid());
                }
            });
        }
        if (CollectionUtils.isEmpty(skuIds)) {
            return resultMap;
        }
        // 通过skuid查询spuid
        GetSpuIdsBySkuIdsDto bySkuIdsDto = new GetSpuIdsBySkuIdsDto();
        bySkuIdsDto.setProductIds(skuIds);
        bySkuIdsDto.setPartnerId(partnerId);
        ProductListDto productListDto = storeItemClient.getSpuIdsBySkuIds(bySkuIdsDto);
        if (ResponseCodeConstant.RESPONSE_SUCCESS.equals(productListDto.getErrcode())
                && CollectionUtils.isNotEmpty(productListDto.getData())) {
            productListDto.getData().stream().forEach(product -> {
                product.getSkuList().stream().forEach(skuProductBean -> {
                    if (resultMap.get(skuProductBean.getSkuId()) != null) {
                        GetProductsVo getProductsVo = resultMap.get(skuProductBean.getSkuId());
                        getProductsVo.setSpuId(product.getPid());
                        getProductsVo.setSpuName(product.getName());
                        String picture = CollectionUtils.isNotEmpty(product.getProductPictureList())
                                ? product.getProductPictureList().get(0).getUrl() : product.getPicture();
                        getProductsVo.setSpuPicture(picture);
                        //getProductsVo.setStatus(product.getStatus());
                        if (CollectionUtils.isNotEmpty(product.getProductAttributeGroupList())
                                && CollectionUtils.isNotEmpty(product.getProductAttributeGroupList().get(0).getAttributeValues())) {
                            List<CartGoods.CartGoodsExtra> extras = new ArrayList<>();
                            List<String> specId = new ArrayList<>();
                            List<String> specName = new ArrayList<>();
                            for (ProductListDto.DataBean.ProductAttributeGroupListBean bean : product.getProductAttributeGroupList()) {
                                for (ProductListDto.DataBean.ProductAttributeGroupListBean.AttributeValueBean attr : bean.getAttributeValues()) {
                                    CartGoods.CartGoodsExtra extra = new CartGoods.CartGoodsExtra();
                                    extra.setAttributeId(attr.getAttributeId());
                                    extra.setAttributeName(attr.getAttributeValue());
                                    specName.add(attr.getAttributeValue());
                                    specId.add(attr.getAttributeId());
                                    break;
                                }
                            }
                            getProductsVo.setExtra(extras);
                            getProductsVo.setDefaultSpecName(StringUtils.join(specName, "/"));
                            getProductsVo.setDefaultSpecId(StringUtils.join(specId, "/"));
                        }
                        resultMap.put(skuProductBean.getSkuId(), getProductsVo);
                    }
                });
            });
        }
        return resultMap;
    }

    @Override
    public Map<String, GetProductBySkuIdResponseBO> getProductsBySkuId(List<String> pids, String partnerId, String storeId, String menuType) {
        Map<String, GetProductBySkuIdResponseBO> resultMap = new HashMap<>();
        if (CollectionUtils.isEmpty(pids)) {
            return resultMap;
        }
        List<String> skuIds = Lists.newArrayList();
        //查询商品详情
        GetProductInfoDto getProductInfoDto = storeItemAdapter.convert2ProductInfoDto(partnerId, storeId, ProductInfoType.ALL.getCode(), pids,menuType);
        ProductInfosDto productInfosDto = storeItemClient.listProductInfos(getProductInfoDto);
        if (ResponseCodeConstant.RESPONSE_SUCCESS.equals(productInfosDto.getErrcode())
                && productInfosDto.getData() != null
                && CollectionUtils.isNotEmpty(productInfosDto.getData().getProducts())) {
            productInfosDto.getData().getProducts().stream().forEach(productBean -> {
                //多规格获取sku信息
                GetProductBySkuIdResponseBO getProductBySkuId = new GetProductBySkuIdResponseBO();
                getProductBySkuId.setSkuId(productBean.getPid());
                getProductBySkuId.setSkuName(productBean.getName());
                String picture = CollectionUtils.isNotEmpty(productBean.getProductPictureList())
                        ? productBean.getProductPictureList().get(0).getUrl() : null;
                getProductBySkuId.setSpuId(productBean.getPid());
                getProductBySkuId.setSpuName(productBean.getName());
                getProductBySkuId.setSpuPicture(picture);
                getProductBySkuId.setOriginalPrice(productBean.getOriginalPrice());
                getProductBySkuId.setFinalPrice(productBean.getFinalPrice());
                getProductBySkuId.setProductAttributeGroupList(productBean.getProductAttributeGroupList());
                getProductBySkuId.setStatus(productBean.getStatus());
                getProductBySkuId.setStock(productBean.getStock());
                getProductBySkuId.setStockLimit(productBean.getStockLimit());
                getProductBySkuId.setCustomerCode(productBean.getCustomerCode());
                getProductBySkuId.setCategory(productBean.getCategory());
                getProductBySkuId.setCategoryName(productBean.getCategoryName());
                resultMap.put(productBean.getPid(), getProductBySkuId);
                getProductBySkuId.setType(1);
                // 规格ID 剔除单品
                if (Objects.equals(productBean.getIsSkuProduct(), YesOrNoEnum.YES.getCode())) {
                    getProductBySkuId.setType(10);
                    skuIds.add(productBean.getPid());
                }
            });
        }
        if (CollectionUtils.isEmpty(skuIds)) {
            return resultMap;
        }
        // 通过skuid查询spuid
        GetSpuIdsBySkuIdsDto bySkuIdsDto = new GetSpuIdsBySkuIdsDto();
        bySkuIdsDto.setProductIds(skuIds);
        bySkuIdsDto.setPartnerId(partnerId);
        ProductListDto productListDto = storeItemClient.getSpuIdsBySkuIds(bySkuIdsDto);
        if (ResponseCodeConstant.RESPONSE_SUCCESS.equals(productListDto.getErrcode())
                && CollectionUtils.isNotEmpty(productListDto.getData())) {
            productListDto.getData().stream().forEach(product -> {
                product.getSkuList().stream().forEach(skuProductBean -> {
                    if (resultMap.get(skuProductBean.getSkuId()) != null) {
                        GetProductBySkuIdResponseBO getProductBySkuId = resultMap.get(skuProductBean.getSkuId());
                        getProductBySkuId.setSpuId(product.getPid());
                        getProductBySkuId.setSpuName(product.getName());
                        String picture = CollectionUtils.isNotEmpty(product.getProductPictureList())
                                ? product.getProductPictureList().get(0).getUrl() : product.getPicture();
                        getProductBySkuId.setSpuPicture(picture);
                        if (CollectionUtils.isNotEmpty(product.getProductAttributeGroupList())
                                && CollectionUtils.isNotEmpty(product.getProductAttributeGroupList().get(0).getAttributeValues())) {
                            List<CartGoods.CartGoodsExtra> extras = new ArrayList<>();
                            List<String> specId = new ArrayList<>();
                            List<String> specName = new ArrayList<>();
                            for (ProductListDto.DataBean.ProductAttributeGroupListBean bean : product.getProductAttributeGroupList()) {
                                for (ProductListDto.DataBean.ProductAttributeGroupListBean.AttributeValueBean attr : bean.getAttributeValues()) {
                                    CartGoods.CartGoodsExtra extra = new CartGoods.CartGoodsExtra();
                                    extra.setAttributeId(attr.getAttributeId());
                                    extra.setAttributeName(attr.getAttributeValue());
                                    specName.add(attr.getAttributeValue());
                                    specId.add(attr.getAttributeId());
                                    break;
                                }
                            }
                            getProductBySkuId.setExtra(extras);
                            getProductBySkuId.setDefaultSpecName(StringUtils.join(specName, "/"));
                            getProductBySkuId.setDefaultSpecId(StringUtils.join(specId, "/"));
                        }
                        resultMap.put(skuProductBean.getSkuId(), getProductBySkuId);
                    }
                });
            });
        }
        return resultMap;
    }


}
