package cn.iocoder.yudao.module.mes.service.stockworkshop;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductCategoryService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
import cn.iocoder.yudao.module.mes.controller.admin.stockworkshop.vo.StockWorkShopTypeEnum;
import cn.iocoder.yudao.module.mes.controller.admin.stockworkshop.vo.StockWorkshopPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.stockworkshop.vo.StockWorkshopRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.stockworkshop.vo.StockWorkshopSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.stockworkshop.StockWorkshopDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.stockworkshop.StockWorkshopDetailDO;
import cn.iocoder.yudao.module.mes.dal.mysql.stockworkshop.StockWorkshopDetailMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.stockworkshop.StockWorkshopMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.STOCK_WORKSHOP_NOT_EXISTS;

/**
 * 车间仓库存 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class StockWorkshopServiceImpl implements StockWorkshopService {

    @Resource
    private StockWorkshopMapper stockWorkshopMapper;

    @Resource
    private StockWorkshopDetailMapper detailMapper;
    @Resource
    private ErpProductService productService;
    @Resource
    private ErpProductUnitService productUnitService;
    @Resource
    private ErpProductCategoryService categoryService;

    @Override
    public Long createStockWorkshop(StockWorkshopSaveReqVO createReqVO) {
        // 插入
        StockWorkshopDO stockWorkshop = BeanUtils.toBean(createReqVO, StockWorkshopDO.class);
        return updateStock(stockWorkshop, StockWorkShopTypeEnum.损耗调整.getValue(), null, null);
        // 返回
    }

    @Override
    public void updateStockWorkshop(StockWorkshopSaveReqVO updateReqVO) {
        // 校验存在
        validateStockWorkshopExists(updateReqVO.getId());
        // 更新
        StockWorkshopDO updateObj = stockWorkshopMapper.selectById(updateReqVO.getId());
        updateObj.setCount(updateReqVO.getCount());
        updateStock(updateObj, StockWorkShopTypeEnum.损耗调整.getValue(), null, null);
        //stockWorkshopMapper.updateById(updateObj);
    }

    //删除车间仓库存，则先做一次损耗调整为0，再删除记录
    @Override
    public void deleteStockWorkshop(Long id) {
        // 校验存在
        StockWorkshopDO stockWorkshop = stockWorkshopMapper.selectById(id);
        stockWorkshop.setCount(stockWorkshop.getCount().multiply(BigDecimal.valueOf(-1)));

        updateStock(stockWorkshop, StockWorkShopTypeEnum.损耗调整.getValue(), null, null);
        // 删除
        stockWorkshopMapper.deleteById(id);
    }

    private void validateStockWorkshopExists(Long id) {
        if (stockWorkshopMapper.selectById(id) == null) {
            throw exception(STOCK_WORKSHOP_NOT_EXISTS);
        }
    }

    @Override
    public StockWorkshopDO getStockWorkshop(Long id) {
        return stockWorkshopMapper.selectById(id);
    }

    @Override
    public PageResult<StockWorkshopDO> getStockWorkshopPage(StockWorkshopPageReqVO pageReqVO) {
        return stockWorkshopMapper.selectPage(pageReqVO);
    }

    @Override
    public List<StockWorkshopRespVO> buildVOList(List<StockWorkshopDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        Map<Long, ErpProductDO> map = productService.getProductMap(
                convertSet(list, StockWorkshopDO::getItemId));
        Map<Long, ErpProductUnitDO> unitMap = productUnitService.getProductUnitMap(
                convertSet(list, StockWorkshopDO::getUnitId));
        Map<Long, ErpProductCategoryDO> cateMap = categoryService.getProductCategoryMap(
                convertSet(list, StockWorkshopDO::getCategoryId));

        return BeanUtils.toBean(list, StockWorkshopRespVO.class, item -> {
            MapUtils.findAndThen(map, item.getItemId(),
                    product -> item.setItemName(product.getName()));
            MapUtils.findAndThen(unitMap, item.getUnitId(),
                    unit -> item.setUnitName(unit.getName()));

            MapUtils.findAndThen(cateMap, item.getCategoryId(),
                    cate -> item.setCategoryName(cate.getName()));
        });
    }

    @Override
    public BigDecimal getStockCount(Long productId) {
        BigDecimal count = stockWorkshopMapper.selectSumByProductId(productId);
        return count != null ? count : BigDecimal.ZERO;
    }

    //更新车间仓库存，itemId不存在则新增
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long updateStock(StockWorkshopDO other, String detailType, Long id, String code) {
        if (other == null)
            throw exception(STOCK_WORKSHOP_NOT_EXISTS);
        Long result = null;
        StockWorkshopDO old = stockWorkshopMapper.selectByItemId(other.getItemId());
        BigDecimal stockCount = other.getCount();
        if (old != null) {
            old.setCount(old.getCount().add(other.getCount()));
            old.setCreateTime(LocalDateTime.now());
            stockWorkshopMapper.updateById(old);
            result = old.getId();
            stockCount = old.getCount();
        } else {
            result = (long) stockWorkshopMapper.insert(other);
        }
        //更新明细
        StockWorkshopDetailDO detailDO = new StockWorkshopDetailDO()
                .setDetailType(detailType)
                .setItemId(other.getItemId())
                .setUnitId(other.getUnitId())
                .setCount(other.getCount())
                .setStockCount(stockCount);
        if (detailType.equals(StockWorkShopTypeEnum.领料入库.getValue())) {
            detailDO.setItemRequisitionCode(code);
            detailDO.setItemRequisitionDetailId(id);
        } else if (detailType.equals(StockWorkShopTypeEnum.投料出库.getValue())) {
            detailDO.setFeedingRecordCode(code);
            detailDO.setFeedingRecordId(id);
        }

        detailMapper.insert(detailDO);
        return result;
    }
}