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

import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutItemMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutMapper;
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService;
import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
import cn.iocoder.yudao.module.mes.controller.admin.stockworkshop.vo.StockWorkShopTypeEnum;
import cn.iocoder.yudao.module.mes.dal.dataobject.stockworkshop.StockWorkshopDO;
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.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.erp.enums.ErrorCodeConstants.*;

// TODO 芋艿：记录操作日志

/**
 * ERP 其它出库单 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class MesStockOutServiceImpl implements MesStockOutService {

    @Resource
    private ErpStockOutMapper stockOutMapper;
    @Resource
    private ErpStockOutItemMapper stockOutItemMapper;

    @Resource
    private ErpProductService productService;

    @Resource
    private ErpStockRecordService stockRecordService;

    @Resource
    private StockWorkshopService stockWorkshopService;
    @Resource
    private StockWorkshopDetailService workshopDetailService;

    private ErpStockOutDO validateStockOutExists(Long id) {
        ErpStockOutDO stockOut = stockOutMapper.selectById(id);
        if (stockOut == null) {
            throw exception(STOCK_OUT_NOT_EXISTS);
        }
        return stockOut;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMesStockOutStatus(Long id, Integer status) {
        boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
        // 1.1 校验存在
        ErpStockOutDO stockOut = validateStockOutExists(id);
        // 1.2 校验状态
        if (stockOut.getStatus().equals(status)) {
            throw exception(approve ? STOCK_OUT_APPROVE_FAIL : STOCK_OUT_PROCESS_FAIL);
        }

        // 2. 更新状态
        int updateCount = stockOutMapper.updateByIdAndStatus(id, stockOut.getStatus(),
                new ErpStockOutDO().setStatus(status));
        if (updateCount == 0) {
            throw exception(approve ? STOCK_OUT_APPROVE_FAIL : STOCK_OUT_PROCESS_FAIL);
        }

        // 3. 变更库存
        List<ErpStockOutItemDO> stockOutItems = stockOutItemMapper.selectListByOutId(id);
        Integer bizType = approve ? ErpStockRecordBizTypeEnum.MES_ITEM_OUT.getType()
                : ErpStockRecordBizTypeEnum.MES_ITEM_OUT_CANCEL.getType();

        stockOutItems.forEach(stockOutItem -> {
            BigDecimal count = approve ? stockOutItem.getCount().negate() : stockOutItem.getCount();
            ErpProductDO productDO = productService.getProduct(stockOutItem.getProductId());
            stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
                    stockOutItem.getProductId(), productDO.getCategoryId(), stockOutItem.getWarehouseId(), count,
                    bizType, stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo(),stockOut.getOutTime()));

        });
        //变更车间仓库存
        // 1.2 产品信息
        Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
                convertSet(stockOutItems, ErpStockOutItemDO::getProductId));

        stockOutItems.forEach(stockOutItem -> {
            Long categoryId = productMap.get(stockOutItem.getProductId()).getCategoryId();
            StockWorkshopDO workshopDO = new StockWorkshopDO(null, stockOutItem.getProductId(),
                    stockOutItem.getCount(), categoryId, stockOutItem.getProductUnitId());
            stockWorkshopService.updateStock(workshopDO, StockWorkShopTypeEnum.领料入库.getValue(),
                    stockOut.getId(), stockOut.getNo());

        });
    }

}