package com.tmerclub.cloud.product.service.impl;

import com.tmerclub.cloud.api.combo.feign.ComboSpuFeignClient;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.constant.StatusEnum;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.order.vo.ShopCartItemVO;
import com.tmerclub.cloud.common.product.vo.ComboSpuVO;
import com.tmerclub.cloud.common.product.vo.SkuVO;
import com.tmerclub.cloud.common.product.vo.SpuVO;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.product.dto.shopcart.CartComboMatchSpuDTO;
import com.tmerclub.cloud.product.dto.shopcart.ChangeShopCartItemDTO;
import com.tmerclub.cloud.product.mapper.ShopCartItemMapper;
import com.tmerclub.cloud.product.model.ShopCartItem;
import com.tmerclub.cloud.product.service.*;
import com.tmerclub.cloud.product.service.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

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

/**
 * @author xxw
 * @date 2022/8/19 11:36
 */
@Service
public class ComboShopCartServiceImpl implements ComboShopCartService {
    @Autowired
    private ShopCartItemMapper shopCartItemMapper;
    @Autowired
    private ShopCartService shopCartService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private SpuService spuService;
    @Autowired
    private SkuStockService skuStockService;
    @DubboReference
    private ComboSpuFeignClient comboSpuFeignClient;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void comboAddCart(ChangeShopCartItemDTO param, List<ShopCartItemVO> shopCartItems) {
        Long userId = AuthUserContext.get().getUserId();
        //套餐skuId
        //根据主商品查找购物车中的搭配商品skuId
        List<ShopCartItemVO> shopCartItemVOList = shopCartItemMapper.getMatchSkuIdList(param.getComboId(), param.getSkuId(), userId);
        List<Long> matchSkuIdList = shopCartItemVOList.stream().map(ShopCartItemVO::getSkuId).collect(Collectors.toList());
        //前端传来的搭配商品skuId
        List<Long> matchSkuIdS = param.getCartComboMatchSpuDTOS().stream().map(CartComboMatchSpuDTO::getSkuId).collect(Collectors.toList());
        //获取主套餐商品购物车id
        Long cartItemId = shopCartService.getCartItemBySpuIdAndComboId(param.getSpuId(), param.getComboId(), AuthUserContext.get().getUserId(), param.getSkuId());
        param.setParentCartItemId(cartItemId);
        //排下序
        Collections.sort(matchSkuIdList);
        Collections.sort(matchSkuIdS);
        boolean equals = matchSkuIdList.equals(matchSkuIdS);
        //==== 判断是否能够加购 =======
        if (Objects.nonNull(cartItemId) && !equals) {
            throw new LuckException("购物车中已存在该规格不同搭配的套餐， 请勿重复加购");
        }
        boolean retainAll = matchSkuIdList.equals(matchSkuIdS);
        //根据主商品和搭配商品查询购物车是否已存在一样的套餐，如果存在直接加数量返回。
        if (retainAll && matchSkuIdS.size() != 0) {
            addComboCount(param, userId);
            return;
        }
        // 购物车套餐没有搭配商品时
        if (matchSkuIdList.size() == 0 && matchSkuIdS.size() == 0) {
            if (Objects.nonNull(cartItemId)) {
                addComboCount(param, userId);
                return;
            }
        }
        //处理套餐主商品加购
        SkuVO skuVo = skuService.getSkuBySkuId(param.getSkuId());
        SpuVO spuVo = spuService.getBySpuId(param.getSpuId());
        //主商品数量
        Integer mainCount = param.getCount() * param.getComboMainLeastNum();
        param.setCount(mainCount);
        disposeCart(param, shopCartItems, true, spuVo, skuVo);
        //获取主套餐商品购物车id
        cartItemId = shopCartService.getCartItemBySpuIdAndComboId(param.getSpuId(), param.getComboId(), AuthUserContext.get().getUserId(), param.getSkuId());
        //处理搭配商品
        List<ChangeShopCartItemDTO> changeShopCartItemDtoS = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<CartComboMatchSpuDTO> cartComboMatchSpuList = param.getCartComboMatchSpuDTOS();
        for (CartComboMatchSpuDTO cartItemDTO : cartComboMatchSpuList) {
            ChangeShopCartItemDTO changeShopCartItemDTO = new ChangeShopCartItemDTO();
            changeShopCartItemDTO.setComboId(param.getComboId());
            changeShopCartItemDTO.setSpuId(cartItemDTO.getSpuId());
            changeShopCartItemDTO.setSkuId(cartItemDTO.getSkuId());
            changeShopCartItemDTO.setCount(cartItemDTO.getCount());
            changeShopCartItemDTO.setParentCartItemId(cartItemId);
            changeShopCartItemDtoS.add(changeShopCartItemDTO);
        }
        //获取商品SPU和SKU信息
        Map<Long, List<SpuVO>> spuMap = new HashMap<>(16);
        Map<Long, List<SkuVO>> skuMap = new HashMap<>(16);
        if (changeShopCartItemDtoS.size() != 0) {
            List<Long> skuIdList = changeShopCartItemDtoS.stream().map(ChangeShopCartItemDTO::getSkuId).collect(Collectors.toList());
            List<Long> spuIdList = changeShopCartItemDtoS.stream().map(ChangeShopCartItemDTO::getSpuId).collect(Collectors.toList());
            List<SpuVO> spuVOList = spuService.listSpuBySpuIds(spuIdList);
            spuMap = spuVOList.stream().collect(Collectors.groupingBy(SpuVO::getSpuId));
            List<SkuVO> skuVOList = skuService.getByIds(skuIdList);
            skuMap = skuVOList.stream().collect(Collectors.groupingBy(SkuVO::getSkuId));
        }
        for (ChangeShopCartItemDTO changeShopCartItemDTO : changeShopCartItemDtoS) {
            disposeCart(changeShopCartItemDTO, shopCartItems, false,
                    spuMap.get(changeShopCartItemDTO.getSpuId()).get(0), skuMap.get(changeShopCartItemDTO.getSkuId()).get(0));
        }
    }


    /**
     * 加购商品
     *
     * @param param
     * @param shopCartItems
     * @param isMainSpu
     * @param spu
     * @param sku
     */
    private void disposeCart(ChangeShopCartItemDTO param, List<ShopCartItemVO> shopCartItems, Boolean isMainSpu, SpuVO spu, SkuVO sku) {
        //主商品判断
        Long userId = AuthUserContext.get().getUserId();
        //判断购物车中是否存在相同sku的主商品
        boolean isAddShopCart = true;
        if (isMainSpu) {
            //前端传来的搭配商品skuId
            List<Long> matchSkuIdS = param.getCartComboMatchSpuDTOS().stream().map(CartComboMatchSpuDTO::getSkuId).collect(Collectors.toList());
            //判断主商品是否存在
            if (Objects.nonNull(param.getParentCartItemId()) && matchSkuIdS.size() == 0) {
                isAddShopCart = false;
            }
        }
        // 当商品状态不正常时，不能添加到购物车
        if (Objects.isNull(spu) || Objects.isNull(sku) || !Objects.equals(spu.getStatus(), StatusEnum.ENABLE.value()) || !Objects.equals(sku.getStatus(), StatusEnum.ENABLE.value()) || !Objects.equals(sku.getSpuId(), spu.getSpuId())) {
            // 当返回商品不存在时，前端应该将商品从购物车界面移除
            throw new LuckException("商品不存在");
        }
        // 保存shopId，不要让前端传过来
        param.setShopId(spu.getShopId());

        // 获取加购的sku库存
        Integer skuStock = getSkuStock(param, sku, spu);
        //判断商品库存是否足够
        if (param.getCount() > 0 && param.getCount() > skuStock) {
            boolean notHasSkuName = CollectionUtils.isEmpty(sku.getSkuLangList()) || ObjectUtils.isEmpty(sku.getSkuLangList().get(0).getSkuName());
            String skuName = notHasSkuName ? "" : " " + sku.getSkuLangList().get(0).getSkuName() + " ";
            throw new LuckException(spu.getName() + skuName + "库存不足");
        }

        //加入的套餐只有主商品没有搭配商品直接增加套餐数量即可
        if (!isAddShopCart) {
            addComboCount(param, userId);
            return;
        }

        // 所有都正常时
        if (Objects.nonNull(skuStock) && skuStock > 0) {
            List<ComboSpuVO> data = comboSpuFeignClient.comboSpuByComboId(param.getComboId()).getData();
            Map<Long, List<ComboSpuVO>> listMap = data.stream().collect(Collectors.groupingBy(ComboSpuVO::getSpuId));
            Integer leastNum = listMap.get(param.getSpuId()).get(0).getLeastNum();
            param.setComboCount(param.getCount() / leastNum);
            shopCartService.addShopCartItem(userId, param, sku.getPriceFee(), spu.getCategoryId());
        }
    }


    /**
     * 购物车套餐数量增加
     *
     * @param param
     * @param userId
     */
    private void addComboCount(ChangeShopCartItemDTO param, Long userId) {
        // 获取加购的sku库存
        SkuVO sku = skuService.getSkuBySkuId(param.getSkuId());
        SpuVO spu = spuService.getBySpuId(param.getSpuId());
        Integer skuStock = getSkuStock(param, sku, spu);
        List<ShopCartItemVO> shopCartItems = new ArrayList<>(Constant.INITIAL_CAPACITY);
        //根据套餐id和主商品sku获取购物车商品信息
        ShopCartItemVO comboMainSpu = shopCartItemMapper.getComboMainSpu(param.getComboId(), param.getSkuId(), userId);
        List<ShopCartItemVO> matchSpuList = shopCartItemMapper.getMatchSpuList(comboMainSpu.getCartItemId());
        //获取套餐搭配商品信息
        shopCartItems.add(comboMainSpu);
        shopCartItems.addAll(matchSpuList);
        //获取套餐商品项信息
        List<ComboSpuVO> comboMatchSpuList = comboSpuFeignClient.comboSpuByComboId(param.getComboId()).getData();
        Map<Long, List<ComboSpuVO>> comboMatchSpuMap = new HashMap<>(16);
        if (Objects.nonNull(comboMatchSpuList) && comboMatchSpuList.size() != 0) {
            comboMatchSpuMap = comboMatchSpuList.stream().collect(Collectors.groupingBy(ComboSpuVO::getSpuId));
        }
        for (ShopCartItemVO shopCartItemVo : shopCartItems) {
            ShopCartItem shopCartItem = new ShopCartItem();
            List<ComboSpuVO> comboSpuList = comboMatchSpuMap.get(shopCartItemVo.getSpuId());
            //套餐商品起搭数
            int leastNum = 0;
            if (Objects.nonNull(comboSpuList) && comboSpuList.size() != 0) {
                leastNum = comboSpuList.get(0).getLeastNum();
            }
            shopCartItem.setUserId(userId);
            shopCartItem.setCount(param.getCount() * leastNum + shopCartItemVo.getCount());
            if (param.getCount() > 0 && param.getCount() > skuStock) {
                boolean notHasSkuName = CollectionUtils.isEmpty(sku.getSkuLangList()) || ObjectUtils.isEmpty(sku.getSkuLangList().get(0).getSkuName());
                String skuName = notHasSkuName ? "" : " " + sku.getSkuLangList().get(0).getSkuName() + " ";
                throw new LuckException(spu.getName() + skuName + "库存不足");
            }
            shopCartItem.setCartItemId(shopCartItemVo.getCartItemId());
            shopCartItem.setIsChecked(shopCartItemVo.getIsChecked());
            shopCartItem.setDiscountId(param.getDiscountId());
            shopCartItem.setComboId(param.getComboId());
            shopCartItem.setComboCount(shopCartItemVo.getComboCount() + param.getCount());
            // 如果有个旧的sku，就说明是在切换sku
            if (Objects.nonNull(param.getOldSkuId())) {
                continue;
            }
            // 防止购物车变成负数，从购物车删除
            if (shopCartItem.getCount() <= 0) {
                shopCartService.deleteShopCartItemsByShopCartItemIds(userId, Collections.singletonList(shopCartItem.getCartItemId()));
                continue;
            }
            shopCartService.updateShopCartItem(userId, shopCartItem);
        }
    }

    private Integer getSkuStock(ChangeShopCartItemDTO param, SkuVO sku, SpuVO spu) {
        Integer skuStock = null;
        if (param.getCount() > 0) {
            // 判断下是否为供应商商品,如果是商家代销供应商商品且为供应商发货设置供应商信息
            if (!Objects.equals(spu.getSupplierId(), 0L) && Objects.equals(spu.getSupplierDeliveryType(), 1)) {
                skuStock = skuStockService.getBySkuId(sku.getSupplierSkuId(), spu.getSpuMold()).getStock();
            } else {
                skuStock = skuStockService.getBySkuId(param.getSkuId(), spu.getSpuMold()).getStock();
            }
        }
        return skuStock;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void comboUpdateCart(ChangeShopCartItemDTO param, List<ShopCartItemVO> shopCartItems) {
        Long userId = AuthUserContext.get().getUserId();
        Integer isMainProd = param.getIsMainProd();
        // 主商品sku切换
        if (Objects.equals(isMainProd, 1)) {
            // 根据新的主商品sku获取购物车已有搭配商品信息
            List<ShopCartItemVO> newShopCartItemVOList = shopCartItemMapper.getMatchSkuIdList(param.getComboId(), param.getSkuId(), userId);
            List<Long> newSkuIdList = newShopCartItemVOList.stream().map(ShopCartItemVO::getSkuId).collect(Collectors.toList());
            // 根据旧的主商品sku获取购物车搭配商品信息
            List<ShopCartItemVO> oldShopCartItemVOList = shopCartItemMapper.getMatchSkuIdList(param.getComboId(), param.getOldSkuId(), userId);
            List<Long> oldSkuIdList = oldShopCartItemVOList.stream().map(ShopCartItemVO::getSkuId).collect(Collectors.toList());
            boolean retainAll = newSkuIdList.equals(oldSkuIdList);
            if (!retainAll && newSkuIdList.size() != 0) {
                throw new LuckException("购物车中已存在该规格不同搭配的套餐， 请勿重复加购");
            }
            // 旧的搭配商品购物车数量
            Map<Long, Integer> oldShopCartSpuCountMap = oldShopCartItemVOList.stream().collect(Collectors.toMap(ShopCartItemVO::getSkuId, ShopCartItemVO::getCount));
            // 旧搭配商品购物车id
            List<Long> oldMachShopCartId = oldShopCartItemVOList.stream().map(ShopCartItemVO::getCartItemId).collect(Collectors.toList());
            oldMachShopCartId.add(param.getShopCartItemId());
            // 旧主商品信息
            ShopCartItemVO oldMainShopCartItemVo = shopCartItemMapper.getByCartId(param.getShopCartItemId());
            // 旧主商品购物车商品数量
            int oldMainSpuCount = oldMainShopCartItemVo.getCount();

            // 把移除的购物车商品数量合并到新的购物车上
            List<ShopCartItem> shopCartItemList = new ArrayList<>(Constant.INITIAL_CAPACITY);
            ShopCartItem shopCartItem;
            ShopCartItemVO cartItemBySpuIdAndComboId = shopCartItemMapper.getCartItemBySpuIdAndComboId(param.getSpuId(), param.getComboId(), userId, param.getSkuId());
            if (Objects.isNull(cartItemBySpuIdAndComboId)) {
                updateShopCart(param, userId);
                return;
            }
            shopCartItem = new ShopCartItem();
            shopCartItem.setCartItemId(cartItemBySpuIdAndComboId.getCartItemId());
            shopCartItem.setCount(cartItemBySpuIdAndComboId.getCount() + oldMainSpuCount);
            shopCartItem.setUserId(userId);
            shopCartItemList.add(shopCartItem);
            // 搭配商品
            for (ShopCartItemVO shopCartItemVO : newShopCartItemVOList) {
                shopCartItem = new ShopCartItem();
                shopCartItem.setCartItemId(shopCartItemVO.getCartItemId());
                shopCartItem.setCount(shopCartItemVO.getCount() + oldShopCartSpuCountMap.get(shopCartItemVO.getSkuId()));
                shopCartItem.setUserId(userId);
                shopCartItemList.add(shopCartItem);
            }
            shopCartItemMapper.updateShopCartItemBatch(shopCartItemList);
            // 移除掉旧的购物车
            shopCartItemMapper.deleteShopCartItemsByShopCartItemIds(userId, oldMachShopCartId);
            return;
        }
        // 搭配商品sku切换
        updateShopCart(param, userId);
    }


    /**
     * 购物车套餐商品sku更换
     *
     * @param param
     * @param userId
     */
    private void updateShopCart(ChangeShopCartItemDTO param, Long userId) {
        SpuVO spu = spuService.getBySpuId(param.getSpuId());
        SkuVO sku = skuService.getSkuBySkuId(param.getSkuId());

        // 获取加购的sku库存
        Integer skuStock = getSkuStock(param, sku, spu);
        ShopCartItem shopCartItem = new ShopCartItem();
        shopCartItem.setUserId(userId);
        shopCartItem.setCartItemId(param.getShopCartItemId());
        // 如果以前就存在这个商品，还要把以前的商品数量累加
        shopCartItem.setCount(param.getCount());
        if (param.getCount() > 0 && shopCartItem.getCount() > skuStock) {
            throw new LuckException("变更的商品规格库存不足");
        }
        shopCartItem.setSkuId(param.getSkuId());
        // 更新购物车
        shopCartService.updateShopCartItem(userId, shopCartItem);
    }
}
