package com.hys.app.service.erp.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hys.app.framework.context.user.AdminUserContext;
import com.hys.app.framework.database.mybatisplus.base.BaseServiceImpl;
import com.hys.app.framework.exception.ServiceException;
import com.hys.app.mapper.erp.ProductStockMapper;
import com.hys.app.mapper.erp.WarehouseMapper;
import com.hys.app.mapper.goods.ProductMapper;
import com.hys.app.model.erp.dos.ProductDO;
import com.hys.app.model.erp.dos.ProductStockDO;
import com.hys.app.model.erp.dos.WarehouseDO;
import com.hys.app.model.erp.dto.ProductStockQueryParams;
import com.hys.app.model.erp.dto.StockDTO;
import com.hys.app.model.erp.vo.ProductStockV1;
import com.hys.app.service.erp.ProductStockManager;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商品库存业务层实现
 *
 * @author 张崧
 * @since 2023-12-07 10:08:44
 */
@Service
@AllArgsConstructor
public class ProductStockManagerImpl extends BaseServiceImpl<ProductStockMapper, ProductStockDO> implements ProductStockManager {

    private WarehouseMapper warehouseMapper;
    private ProductMapper productMapper;

    @Override
    public void addProduct(ProductDO productDO) {
        List<WarehouseDO> list = warehouseMapper.selectList(new LambdaQueryWrapper<WarehouseDO>().eq(WarehouseDO::getCompanyId, AdminUserContext.getCompanyId()));
        if (CollUtil.isNotEmpty(list)) {
            List<ProductStockDO> stockList = new ArrayList<>();
            for (WarehouseDO warehouseDO : list) {
                ProductStockDO productStockDO = new ProductStockDO();
                productStockDO.setProductId(productDO.getId());
                productStockDO.setWarehouseId(warehouseDO.getId());
                productStockDO.setCompanyId(AdminUserContext.getCompanyId());
                stockList.add(productStockDO);
            }
            super.saveBatch(stockList);
        }
    }

    //    @Autowired
//    private ProductStockConverter converter;
//
//    @Autowired
//    private WarehouseManager warehouseManager;
//
//    @Autowired
//    private ProductMapper productMapper;
//
//    @Autowired
//    private ProductStockMapper productStockMapper;
//
//    @Autowired
//    private GoodsMapper goodsMapper;
//
//    @Override
//    public WebPage<ProductStockVO> list(ProductStockQueryParams queryParams) {
//        WebPage<ProductStockDO> webPage = baseMapper.selectPage(queryParams);
//        return converter.convert(webPage);
//    }
//
//    @Override
//    public ProductStockDO getOne(String id) {
//        return productStockMapper.getOne(id);
//    }
//
//    /**
//     * 获取仓库列表
//     *
//     * @param request
//     * @return
//     */
    @Override
    public List<ProductStockV1> selectList(ProductStockQueryParams request) {
        request.setCompanyId(AdminUserContext.getCompanyId());
        List<ProductStockV1> productStockV1s = baseMapper.queryList(request);
        for (ProductStockV1 productStockV1 : productStockV1s) {
            productStockV1.setProductVO(productMapper.selectById(productStockV1.getProductId()));
        }
        return productStockV1s;
    }
//
//    /**
//     * 获取仓库列表
//     *
//     * @param request
//     * @return
//     */
    @Override
    public Long selectCount(ProductStockQueryParams request) {
        return baseMapper.selectCount(request);
    }
//
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void initStockByProduct(Long goodsId) {
//        List<WarehouseDO> list1 = warehouseManager.list(new LambdaQueryWrapper<WarehouseDO>().eq(WarehouseDO::getDeleted, 0));
//        List<ProductStockDO> list = new ArrayList<>();
//        for (WarehouseDO warehouseDO : list1) {
//            ProductStockDO productStockDO = new ProductStockDO();
//            productStockDO.setWarehouseId(warehouseDO.getId());
//            productStockDO.setGoodsId(goodsId);
//            list.add(productStockDO);
//        }
//        super.saveBatch(list);
//    }
//
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void initStockByWarehouse(Long warehouseId) {
        List<ProductDO> list = productMapper.selectList(new LambdaQueryWrapper<ProductDO>().eq(ProductDO::getCompanyId, AdminUserContext.hasCompany()));
        if (CollUtil.isNotEmpty(list)){
            List<ProductStockDO> arrayList = new ArrayList<>();
            for (ProductDO aDo : list) {
                ProductStockDO stockDO = new ProductStockDO();
                stockDO.setWarehouseId(warehouseId);
                stockDO.setProductId(aDo.getId());
                stockDO.setCompanyId(AdminUserContext.getCompanyId());
                arrayList.add(stockDO);
            }
            saveBatch(arrayList);
        }

    }
//
//    @Override
//    public void deleteStockByProduct(List<Long> productIds) {
//    }
//
//
//    @Override
//    public void deleteByIds(List<Long> ids) {
//        if (ids.isEmpty()) {
//            return;
//        }
//        productStockMapper.deleteBatchIds(ids);
//    }
//
//    @Override
//    public void deleteStockByWarehouse(Long warehouseId) {
//        // 目前注释掉下面的代码，暂时先不需要删除产品库存数据，因为比如入库单退货时要扣批次的库存，批次库存和产品库存应该是保持一致的
////        lambdaUpdate().eq(ProductStockDO::getWarehouseId, warehouseId).remove();
//    }
//
//    /**
//     * 查询商品库存预警分页列表数据
//     *
//     * @param pageNo      分页数
//     * @param pageSize    每页数量
//     * @param warehouseId 仓库ID
//     * @param deptId      部门ID
//     * @param name        商品名称
//     * @return
//     */
//    @Override
//    public WebPage<ProductStockWarningVO> listWarningStock(Long pageNo, Long pageSize, Long warehouseId, Long deptId, String name) {
//        IPage<ProductStockWarningVO> iPage = this.productStockMapper.listWarningStockPage(new Page(pageNo, pageSize), warehouseId, deptId, name);
//        return PageConvert.convert(iPage);
//    }
//
//    /**
//     * 获取某个仓库中某个商品的库存信息
//     *
//     * @param productId   产品ID
//     * @param warehouseId 仓库ID
//     * @return
//     */
//    @Override
//    public ProductStockDO getStock(Long productId, Long warehouseId) {
//        return this.lambdaQuery()
//                .eq(ProductStockDO::getProductId, productId)
//                .eq(ProductStockDO::getWarehouseId, warehouseId)
//                .one();
//    }
//
//    @Override
//    public List<ProductStockDO> listByWarehouseAndProduct(List<Long> warehouseIds, List<Long> productIds) {
//        if (CollUtil.isEmpty(productIds)) {
//            return Collections.emptyList();
//        }
//        return lambdaQuery()
//                .in(warehouseIds != null, ProductStockDO::getWarehouseId, warehouseIds)
//                .in(ProductStockDO::getProductId, productIds)
//                .list();
//    }
//
//    @Override
//    public Map<Long, Integer> queryStockNum(List<Long> warehouseIds, List<Long> productIds) {
//        // 批量查询库存
//        List<ProductStockDO> productStockList = listByWarehouseAndProduct(warehouseIds, productIds);
//        // 按产品分组
//        Map<Long, List<ProductStockDO>> groupByProduct = productStockList.stream().collect(Collectors.groupingBy(ProductStockDO::getProductId));
//        // 循环每个产品，计算产品的总库存
//        return productIds.stream().collect(Collectors.toMap(Function.identity(), productId -> {
//            List<ProductStockDO> stockList = groupByProduct.get(productId);
//            return stockList == null ? 0 : stockList.stream().mapToInt(ProductStockDO::getNum).sum();
//        }));
//    }
//
//    /**
//     * 该方法不应该单独调用，应该在更新批次是调用
//     */
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void updateStock(Long warehouseId, Long productId, StockOperateEnum operate, int changeNum) {
//        if (changeNum <= 0) {
//            throw new ServiceException("库存变更数量必须大于0");
//        }
//
//        boolean update = lambdaUpdate()
//                .setSql("num = num + " + (operate == StockOperateEnum.Increase ? changeNum : -changeNum))
//                .eq(ProductStockDO::getWarehouseId, warehouseId)
//                .eq(ProductStockDO::getProductId, productId)
//                // 如果是扣减库存，需要校验剩余库存是否充足
//                .ge(operate == StockOperateEnum.Reduce, ProductStockDO::getNum, changeNum)
//                .update();
//
//        if (!update) {
//            // 因为都是基于批次来更新仓库库存，只要批次校验没问题，这里就没问题，走到这里应该是代码有bug
//            throw new ServiceException("库存更新失败，请联系管理员排查：" + warehouseId + "_" + productId);
//        }
//    }
//
//    @Override
//    public void intStock(List<ProductDO> bean, GoodsDO goodsDO) {
//        List<WarehouseDO> list = warehouseManager.list(new LambdaQueryWrapper<WarehouseDO>().eq(WarehouseDO::getCompanyId, AdminUserContext.hasCompany()));
//        if (CollUtil.isNotEmpty(list)) {
//            List<ProductStockDO> arrayList = new ArrayList<>();
//            for (ProductDO aDo : bean) {
//                for (WarehouseDO warehouseDO : list) {
//                    ProductStockDO aDo1 = new ProductStockDO();
//                    aDo1.setWarehouseId(warehouseDO.getId());
//                    aDo1.setGoodsId(aDo.getGoodsId());
//                    aDo1.setGoodsName(goodsDO.getName());
//                    aDo1.setGoodsBarCode(aDo.getSku());
//                    aDo1.setGoodsSnCode(goodsDO.getSn());
//                    aDo1.setHireOrSail(aDo.getHireOrSail());
//                    aDo1.setProductId(aDo.getId());
//                    arrayList.add(aDo1);
//                }
//            }
//            saveBatch(arrayList);
//        }
//    }
//
    @Override
    public void updateLockedStock(List<StockDTO> ids) {
        List<Long> collect = ids.stream().map(StockDTO::getId).collect(Collectors.toList());
        List<ProductStockDO> list = list(new LambdaQueryWrapper<ProductStockDO>().in(ProductStockDO::getId, collect));
        if (list.size() != ids.size()) {
            throw new ServiceException("部分库存信息记录未查询到");
        }
        for (ProductStockDO aDo : list) {
            StockDTO stockDTO = ids.stream().filter(item -> item.getId().equals(aDo.getId())).findFirst().get();
            Integer currentLocked = aDo.getLockedStock() + stockDTO.getNum();
            aDo.setLockedStock(currentLocked);
            aDo.setUsableStock(aDo.getActualStock() - currentLocked);
        }
        updateBatchById(list);
    }
//
    @Override
    public void updateActualStock(List<StockDTO> ids, String inventory) {
        List<Long> collect = ids.stream().map(StockDTO::getId).collect(Collectors.toList());
        List<ProductStockDO> list = list(new LambdaQueryWrapper<ProductStockDO>().in(ProductStockDO::getId, collect));
        if (list.size() != ids.size()) {
            throw new ServiceException("部分库存信息记录未查询到");
        }
        for (ProductStockDO aDo : list) {
            StockDTO stockDTO = ids.stream().filter(item -> item.getId().equals(aDo.getId())).findFirst().get();
            aDo.setActualStock(aDo.getActualStock() + stockDTO.getNum());
            if (StrUtil.isNotBlank(inventory) && "inventory".equals(inventory)) {
                aDo.setActualStock(stockDTO.getNum());
            }
            aDo.setUsableStock(aDo.getActualStock() - aDo.getLockedStock());
        }
        updateBatchById(list);
    }
//
//    @Override
//    public void updateTransitStock(List<StockDTO> ids) {
//        List<Long> collect = ids.stream().map(StockDTO::getId).collect(Collectors.toList());
//        List<ProductStockDO> list = list(new LambdaQueryWrapper<ProductStockDO>().in(ProductStockDO::getId, collect));
//        if (list.size() != ids.size()) {
//            throw new ServiceException("部分库存信息记录未查询到");
//        }
//        for (ProductStockDO aDo : list) {
//            StockDTO stockDTO = ids.stream().filter(item -> item.getId().equals(aDo.getId())).findFirst().get();
//            aDo.setTransitStock(aDo.getTransitStock() + stockDTO.getNum());
//        }
//        updateBatchById(list);
//    }
}

