package com.tmerclub.cloud.product.feign;



import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.tmerclub.cloud.api.product.feign.SkuStockFeignClient;
import com.tmerclub.cloud.api.product.vo.SkuStockVO;
import com.tmerclub.cloud.common.product.constant.SupplierDeliveryType;
import com.tmerclub.cloud.common.product.vo.SkuComboVO;
import com.tmerclub.cloud.common.cache.constant.LuaOperateEnum;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.product.constant.SpuMold;
import com.tmerclub.cloud.common.product.dto.StockPointSkuDTO;
import com.tmerclub.cloud.common.product.vo.SkuVO;
import com.tmerclub.cloud.common.product.vo.SpuVO;
import com.tmerclub.cloud.common.product.vo.StockPointSkuVO;
import com.tmerclub.cloud.common.product.vo.search.SpuAdminVO;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.product.manager.StockManager;
import com.tmerclub.cloud.product.service.*;
import com.tmerclub.cloud.product.service.*;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

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

/**
 * @author xxw
 * @date 2022/11/17 15:29
 */
@DubboService
public class SkuStockFeignController implements SkuStockFeignClient {
    @Autowired
    private SkuStockService skuStockService;
    @Autowired
    private StockPointSkuService stockPointSkuService;
    @Autowired
    private SkuComboService skuComboService;
    @Autowired
    private SpuService spuService;
    @Autowired
    private StockManager stockManager;
    @Autowired
    private SkuService skuService;

    @Override
    public ServerResponseEntity<Map<Long, Integer>> getStockMapBySkuIdAndStockPointIds(Long skuId, List<Long> stockPointIds){
        List<StockPointSkuVO> stockPointSkuList = new ArrayList<>(stockPointIds.size());
        for (Long stockPointId : stockPointIds) {
            StockPointSkuVO stockPointSkuVO = new StockPointSkuVO();
            stockPointSkuVO.setStockPointId(stockPointId);
            stockPointSkuVO.setSkuId(skuId);
            stockPointSkuList.add(stockPointSkuVO);
        }
        List<SkuStockVO> skuStockVOList = skuStockService.listSkuStockBySkuIds(stockPointSkuList);
        Map<Long, Integer> stockMap = skuStockVOList.stream().collect(Collectors.toMap(SkuStockVO::getStockPointId, SkuStockVO::getStock));
        return ServerResponseEntity.success(stockMap);
    }

    @Override
    public Map<String, SkuStockVO> listSkuStock(List<SkuStockVO> skuStocks) {
        // 转成Map形式方便获取(key: skuId_stockPontId)
        Map<String, SkuStockVO> stockVOMap = stockManager.mapSkuStockBySkuStocks(skuStocks);
        return stockVOMap;
    }

    @Override
    public void changeSkuStock(List<SkuStockVO> stockVOList) {
        skuStockService.changeSkuStock(stockVOList);
    }

    @Override
    public List<Long> checkStockPointContainSku(List<Long> stockPointIds, List<Long> skuIds) {
        return stockPointSkuService.checkStockPointContainSku(stockPointIds, skuIds);
    }

    @Override
    public ServerResponseEntity<Void> addAndUpdateStockPoint(Long spuId, List<StockPointSkuDTO> stockPointSkuVOList) {
        if (CollectionUtils.isEmpty(stockPointSkuVOList)) {
            return ServerResponseEntity.success();
        }
        // 过滤一下已经被删除的仓库和门店或改为共享模式的门店
        List<StockPointSkuDTO> filtePointList = stockPointSkuService.filtePoint(stockPointSkuVOList);
        // 处理关联数据
        stockPointSkuService.changeStockPoint(filtePointList, false);
        // 修改redis缓存
        List<SkuStockVO> skuStockList = new ArrayList<>(filtePointList.size());
        for (StockPointSkuDTO stockPointSku : filtePointList) {
            skuStockList.add(new SkuStockVO(stockPointSku.getSkuId(), stockPointSku.getStock(), null, null, stockPointSku.getStockPointId()));
        }
        skuStockService.handSkuStock(spuId, skuStockList, LuaOperateEnum.SKU_ADD, true);
        // 生成入库记录
        skuService.loadSeckillStockBillLogItems(spuId, filtePointList);
        // 清理一下缓存
        spuService.removeSpuCacheBySpuId(spuId);
        return ServerResponseEntity.success();
    }

    @Override
    public ServerResponseEntity<Map<Long, Integer>> calculateStockByComboSpuList(List<Long> spuIds) {
        List<SkuComboVO> skuComboList = skuComboService.getCombSpusBySpuIds(spuIds);
        if(CollectionUtil.isEmpty(skuComboList)){
            HashMap<Long, Integer> spuMap = new HashMap<>(Constant.INITIAL_CAPACITY);
            for (Long spuId : spuIds) {
                spuMap.put(spuId,0);
            }
            return ServerResponseEntity.success(spuMap);
        }
        Map<Long, List<SkuComboVO>> spuMap = skuComboList.stream().collect(Collectors.groupingBy(SkuComboVO::getSpuId));
        // 获取所有组合的商品库存
        List<Long> comboSkuIds = skuComboList.stream().map(SkuComboVO::getComboSkuId).toList();
        List<StockPointSkuVO> stockPointList = stockPointSkuService.listPointIdsBySkuIds(comboSkuIds);
        // 获取库存
        List<SkuStockVO> skuStockList = skuStockService.listSkuStockBySkuIds(stockPointList);
        Map<Long, List<SkuStockVO>> skuStockMap = skuStockList.stream().collect(Collectors.groupingBy(SkuStockVO::getSkuId));
        Map<Long, List<SkuComboVO>> skuComboMap = skuComboList.stream().collect(Collectors.groupingBy(SkuComboVO::getSkuId));
        Long shopId = AuthUserContext.get().getTenantId();
        Map<Long,Integer> spuStockMap = new HashMap<>(spuIds.size());
        for (Long spuId : spuIds) {
            List<SkuComboVO> skuComboVOList = spuMap.get(spuId);
            if(CollectionUtil.isEmpty(skuComboVOList)){
                spuStockMap.put(spuId,0);
                continue;
            }
            // 累加上sku的所有组合商品的所有仓库的库存最小值,就是当前sku可用的最小库存
            int totalStock = 0;
            Set<Long> skuIds = skuComboVOList.stream().map(SkuComboVO::getSkuId).collect(Collectors.toSet());
            // 当前商品的所有sku
            for (Long skuId : skuIds) {
//                Map<Long, Integer> pointStockMap = new HashMap<>(stockPointList.size());
                List<SkuComboVO> comboSpuList = skuComboMap.get(skuId);
                // 判断是否有相同供货区域
                List<Long> skuList = comboSpuList.stream().map(SkuComboVO::getComboSkuId).collect(Collectors.toList());
                if (!skuService.hasStockBySkuIds(skuList, shopId)) {
                    continue;
                }
                List<Integer> comboStockList = new ArrayList<>(comboSpuList.size());
                // 当前sku的组合商品列表
                for (SkuComboVO skuComboDb : comboSpuList) {
                    int comboStock = 0;
                    if (!skuStockMap.containsKey(skuComboDb.getComboSkuId())) {
                        continue;
                    }
                    // 当前组合商品的所有仓库库存列表
                    List<SkuStockVO> stockList = skuStockMap.get(skuComboDb.getComboSkuId());
                    for (SkuStockVO skuStockVO : stockList) {
                        // 如果是0就是总库存
                        if (Objects.equals(skuStockVO.getStockPointId(), StockManager.WAREHOUSE_ID)) {
                            continue;
                        }
                        // 除以组合数量向下取整得出 当前的组合商品-当前仓库 可用库存
                        int pointStock = Math.floorDiv(skuStockVO.getStock(), skuComboDb.getComboCount());
                        // 组合商品的库存取最小值,比如都是默认仓库的情况下,取最小值
//                        if (!pointStockMap.containsKey(skuStockVO.getStockPointId()) || pointStockMap.get(skuStockVO.getStockPointId()) > pointStock) {
//                            pointStockMap.put(skuStockVO.getStockPointId(), pointStock);
//                        }
                        comboStock += pointStock;
                    }
                    comboStockList.add(comboStock);
                }
//                for (Long pointId : pointStockMap.keySet()) {
//                    totalStock += pointStockMap.get(pointId);
//                }
                totalStock = totalStock + Collections.min(comboStockList);
            }
            spuStockMap.put(spuId,totalStock);
        }
        return ServerResponseEntity.success(spuStockMap);
    }

    @Override
    public ServerResponseEntity<Void> updateStockMode(Long stockPointId, Integer stockMode, Integer type) {
        skuService.updateStockMode(stockPointId, stockMode, type);
        return ServerResponseEntity.success();
    }

    @Override
    public ServerResponseEntity<List<SpuAdminVO>> loadProdStock(List<SpuAdminVO> spuAdminList) {
        // 商品id列表
        List<Long> spuIds = spuAdminList.stream().map(SpuAdminVO::getSpuId).collect(Collectors.toList());
        Map<Long, SpuVO> spuMap = spuService.mapSpuByCache(spuIds);
        Set<Long> skuIds = new HashSet<>(Constant.INITIAL_CAPACITY);
        Map<Long, List<SkuComboVO>> supplierSkuComboMap = new HashMap<>(Constant.INITIAL_CAPACITY);
        // 获取
        for (SpuVO spuVO : spuMap.values()) {
            Boolean isSupplierSpu = Objects.equals(spuVO.getSupplierDeliveryType(), SupplierDeliveryType.SUPPLIER_DELIVERY.value());
            // 组合商品的sku处理
            if (Objects.equals(spuVO.getSpuMold(), SpuMold.COMBO.value())) {
                if (isSupplierSpu) {
                    // 供应商的组合商品处理
                    SpuVO supplierSpu = spuService.getBySpuId(spuVO.getSupplierSpuId());
                    for (SkuVO sku : supplierSpu.getSkus()) {
                        supplierSkuComboMap.put(sku.getSkuId(),sku.getSkuComboList());
                    }
                }
                for (SkuVO skuVO : spuVO.getSkus()) {
                    List<SkuComboVO> skuComboList = skuVO.getSkuComboList();
                    // 如果是供应商的组合商品直接获取供应商的
                    if(isSupplierSpu && supplierSkuComboMap.containsKey(skuVO.getSupplierSkuId())){
                        skuComboList = supplierSkuComboMap.get(skuVO.getSupplierSkuId());
                    }
                    // 添加组合的skuId
                    skuIds.addAll(skuComboList.stream().map(SkuComboVO::getComboSkuId).collect(Collectors.toSet()));
                }
                continue;
            }
            for (SkuVO sku : spuVO.getSkus()) {
                skuIds.add(sku.getSkuId());
                if (Objects.nonNull(sku.getSupplierSkuId())) {
                    skuIds.add(sku.getSupplierSkuId());
                }
            }
        }
        Map<Long, SkuStockVO> skuStockMap = skuStockService.mapSkuTotalStockBySkuIds(new ArrayList<>(skuIds));
        for (SpuAdminVO spuAdminVO : spuAdminList) {
            SpuVO spuVO = spuMap.get(spuAdminVO.getSpuId());
            Boolean isSupplierSpu = Objects.equals(spuVO.getSupplierDeliveryType(), SupplierDeliveryType.SUPPLIER_DELIVERY.value());
            Map<Long, SkuVO> skuVOMap = new HashMap<>(Constant.INITIAL_CAPACITY);
            if (CollectionUtil.isNotEmpty(spuAdminVO.getSkuList())) {
                skuVOMap = spuAdminVO.getSkuList().stream().collect(Collectors.toMap(SkuVO::getSkuId, s -> s));
            }
            int stock = 0;
            // 组合商品的sku处理
            if (Objects.equals(spuVO.getSpuMold(), SpuMold.COMBO.value())) {
                for (SkuVO sku : spuVO.getSkus()) {
                    List<SkuComboVO> skuComboList = sku.getSkuComboList();
                    if(isSupplierSpu && supplierSkuComboMap.containsKey(sku.getSupplierSkuId())){
                        skuComboList = supplierSkuComboMap.get(sku.getSupplierSkuId());
                    }
                    int minComboStock = 0;
                    for (int i = 0; i < skuComboList.size(); i++) {
                        SkuComboVO skuComboVO = skuComboList.get(i);
                        SkuStockVO skuStockVO = skuStockMap.get(skuComboVO.getComboSkuId());
                        if (skuVOMap.containsKey(sku.getSkuId())) {
                            skuVOMap.get(sku.getSkuId()).setStock(skuStockVO.getStock());
                        }
                        int comboStock = Objects.isNull(skuComboVO.getComboCount()) ? 0 : skuStockVO.getStock() / skuComboVO.getComboCount();
                        if (i == 0 || minComboStock > comboStock) {
                            minComboStock = comboStock;
                        }
                    }
                    stock += minComboStock;
                }
                continue;
            } else {
                if (Objects.equals(spuAdminVO.getSupplierDeliveryType(), SupplierDeliveryType.SUPPLIER_DELIVERY.value())) {
                    if (CollectionUtil.isNotEmpty(spuAdminVO.getSkuList())) {
                        for (SkuVO skuVO : spuAdminVO.getSkuList()) {
                            skuVO.setStock(skuStockMap.get(skuVO.getSupplierSkuId()).getStock());
                        }
                    }
                    continue;
                }
                for (SkuVO sku : spuVO.getSkus()) {
                    SkuStockVO skuStockVO = skuStockMap.get(sku.getSkuId());
                    if (skuVOMap.containsKey(sku.getSkuId())) {
                        skuVOMap.get(sku.getSkuId()).setStock(skuStockVO.getStock());
                    }
                    stock += skuStockVO.getStock();
                }
            }
            spuAdminVO.setStock(stock);
        }
        return ServerResponseEntity.success(spuAdminList);
    }

    @Override
    public ServerResponseEntity<Map<String, SkuStockVO>> mapSkuPointStockByStockPoints(List<StockPointSkuVO> productSearchList) {
        if (CollUtil.isEmpty(productSearchList)) {
            return ServerResponseEntity.success(Collections.emptyMap());
        }
        return ServerResponseEntity.success(skuStockService.mapSkuPointStockByStockPoints(productSearchList));
    }
}
