package com.hw.wms.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import com.hw.common.core.constant.SecurityConstants;
import com.hw.common.core.constant.WmsConstants;
import com.hw.common.core.domain.R;
import com.hw.common.core.exception.ServiceException;
import com.hw.common.core.utils.uuid.Seq;
import com.hw.common.security.utils.SecurityUtils;
import com.hw.mes.api.RemoteMesService;
import com.hw.mes.api.domain.MesBaseBarcodeInfo;
import com.hw.wms.domain.*;
import com.hw.wms.mapper.*;
import com.hw.wms.service.IWmsTransactionalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

import com.hw.common.core.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.hw.wms.service.IWmsTransferService;

import javax.annotation.Resource;

/**
 * 转库记录Service业务层处理
 *
 * @author xins
 * @date 2024-01-12
 */
@Service
public class WmsTransferServiceImpl implements IWmsTransferService {
    @Autowired
    private WmsTransferMapper wmsTransferMapper;

    @Autowired
    private WmsTransferDetailMapper wmsTransferDetailMapper;

    @Autowired
    private WmsBaseLocationMapper wmsBaseLocationMapper;

    @Autowired
    private WmsProductStockMapper wmsProductStockMapper;

    @Autowired
    private IWmsTransactionalService wmsTransactionalService;

    @Autowired
    private WmsBaseWarehouseMapper wmsBaseWarehouseMapper;

    @Resource
    private RemoteMesService remoteMesService;

    /**
     * 查询转库记录
     *
     * @param transferId 转库记录主键
     * @return 转库记录
     */
    @Override
    public WmsTransfer selectWmsTransferByTransferId(Long transferId) {
        return wmsTransferMapper.selectWmsTransferByTransferId(transferId);
    }

    /**
     * 查询转库记录列表
     *
     * @param wmsTransfer 转库记录
     * @return 转库记录
     */
    @Override
    public List<WmsTransfer> selectWmsTransferList(WmsTransfer wmsTransfer) {
        return wmsTransferMapper.selectWmsTransferList(wmsTransfer);
    }

    /**
     * 新增转库记录
     *
     * @param wmsTransfer 转库记录
     * @return 结果
     */
    @Transactional
    @Override
    public int insertWmsTransfer(WmsTransfer wmsTransfer) {
        int rows = wmsTransferMapper.insertWmsTransfer(wmsTransfer);
        insertWmsTransferDetail(wmsTransfer);
        return rows;
    }

    /**
     * 修改转库记录
     *
     * @param wmsTransfer 转库记录
     * @return 结果
     */
    @Transactional
    @Override
    public int updateWmsTransfer(WmsTransfer wmsTransfer) {
        wmsTransferMapper.deleteWmsTransferDetailByTransferId(wmsTransfer.getTransferId());
        insertWmsTransferDetail(wmsTransfer);
        return wmsTransferMapper.updateWmsTransfer(wmsTransfer);
    }

    /**
     * 批量删除转库记录
     *
     * @param transferIds 需要删除的转库记录主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteWmsTransferByTransferIds(Long[] transferIds) {
        wmsTransferMapper.deleteWmsTransferDetailByTransferIds(transferIds);
        return wmsTransferMapper.deleteWmsTransferByTransferIds(transferIds);
    }

    /**
     * 删除转库记录信息
     *
     * @param transferId 转库记录主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteWmsTransferByTransferId(Long transferId) {
        wmsTransferMapper.deleteWmsTransferDetailByTransferId(transferId);
        return wmsTransferMapper.deleteWmsTransferByTransferId(transferId);
    }

    /**
     * 新增转库记录明细;移库合库记录对应的明细信息信息
     *
     * @param wmsTransfer 转库记录对象
     */
    public void insertWmsTransferDetail(WmsTransfer wmsTransfer) {
        List<WmsTransferDetail> wmsTransferDetailList = wmsTransfer.getWmsTransferDetailList();
        Long transferId = wmsTransfer.getTransferId();
        if (StringUtils.isNotNull(wmsTransferDetailList)) {
            List<WmsTransferDetail> list = new ArrayList<WmsTransferDetail>();
            for (WmsTransferDetail wmsTransferDetail : wmsTransferDetailList) {
                wmsTransferDetail.setTransferId(transferId);
                list.add(wmsTransferDetail);
            }
            if (list.size() > 0) {
                wmsTransferMapper.batchWmsTransferDetail(list);
            }
        }
    }


    /**
     * 申请转库（适合五楼半成品库入成品库）
     *
     * @param wmsTransfers
     * @return
     */
    @Override
    public int applyTransfers(List<WmsTransfer> wmsTransfers) {
        String userName = SecurityUtils.getUsername();
        Date currentDate = new Date();
        //todo:生成任务编号
        //需要在循环内执行事务，不能用this调用，需要新建一个Service
        wmsTransfers.forEach(wmsTransfer -> {
            wmsTransactionalService.applyTransfer(wmsTransfer, userName, currentDate);
        });

        return 1;
    }

    /**
     * 查询转库记录列表，Join原仓库，目标仓库和物料
     *
     * @param wmsTransfer 转库记录
     * @return 转库记录
     */
    @Override
    public List<WmsTransfer> selectWmsTransferJoinList(WmsTransfer wmsTransfer) {
        return wmsTransferMapper.selectWmsTransferJoinList(wmsTransfer);
    }


    /**
     * 转库出库，适合五楼半成品出半成品库
     *
     * @param wmsTransferDetail
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int transferOutstock(WmsTransferDetail wmsTransferDetail) {
        String userName = SecurityUtils.getUsername();
        Date currentDate = new Date();
        String oriLocationCode = wmsTransferDetail.getLocationCode();

        String materialBarcode = wmsTransferDetail.getMaterialBarcode();

        R<MesBaseBarcodeInfo> mesBaseBarcodeInfoR = remoteMesService.getBarcode(materialBarcode, SecurityConstants.INNER);
        if (mesBaseBarcodeInfoR == null) {
            throw new ServiceException("物料编码错误");
        }
        MesBaseBarcodeInfo mesBaseBarcodeInfo = mesBaseBarcodeInfoR.getData();
        if (mesBaseBarcodeInfo == null) {
            throw new ServiceException("物料编码错误");
        }


        WmsTransfer queryTransfer = new WmsTransfer();
        queryTransfer.setOriLocationCode(oriLocationCode);
        queryTransfer.setProductBatch(materialBarcode);
        queryTransfer.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_NOT_FINISH);
        List<WmsTransfer> wmsTransfers = wmsTransferMapper.selectWmsTransferList(queryTransfer);
        if (wmsTransfers != null && !wmsTransfers.isEmpty()) {
            throw new ServiceException("有此库位出库任务，请不要重复出库");
        }

        WmsBaseLocation oriLocation = wmsBaseLocationMapper.selectWmsBaseLocationByLocationCode(oriLocationCode);
        if (oriLocation == null) {
            throw new ServiceException("库位不存在");
        }

        //删除成品库存
        WmsProductStock productStock = wmsProductStockMapper.selectProductStockByBatch(materialBarcode);
        if (productStock == null) {
            throw new ServiceException("无此成品库存");
        }

        WmsTransfer wmsTransfer = new WmsTransfer();
        wmsTransfer.setTaskCode(Seq.getId(Seq.wmsTransferSeqType, Seq.wmsTransferSeqCode));
        wmsTransfer.setOriWarehouseId(oriLocation.getWarehouseId());
        wmsTransfer.setOriLocationCode(oriLocationCode);
        wmsTransfer.setMaterialId(mesBaseBarcodeInfo.getMaterialId());
        wmsTransfer.setProductBatch(materialBarcode);
        wmsTransfer.setApplyQty(BigDecimal.ONE);
        wmsTransfer.setOutstockQty(BigDecimal.ONE);
        wmsTransfer.setOperationType(WmsConstants.WMS_OPERATION_TYPE_MANUAL);
        wmsTransfer.setTransferType(WmsConstants.WMS_TRANSFER_TYPE_OUT_TO_PRODUCT_STOCK);
        wmsTransfer.setAuditStatus(WmsConstants.WMS_AUDIT_STATUS_PASS);
        wmsTransfer.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_EXECUTING);
        wmsTransfer.setApplyBy(userName);
        wmsTransfer.setApplyDate(currentDate);
        wmsTransfer.setBeginTime(currentDate);

        wmsTransferMapper.insertWmsTransfer(wmsTransfer);

        //插入转库任务明细
        wmsTransferDetail.setTransferId(wmsTransfer.getTransferId());
        wmsTransferDetail.setMaterialId(mesBaseBarcodeInfo.getMaterialId());
        wmsTransferDetail.setRealAmount(BigDecimal.ONE);
        wmsTransferDetail.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_FINISH);
        wmsTransferDetail.setTransferDetailType(WmsConstants.WMS_TRANSFER_DETAIL_TYPE_OUTSTOCK);
        wmsTransferDetail.setCreateBy(userName);
        wmsTransferDetail.setCreateDate(currentDate);
        wmsTransferDetail.setExecutePerson(userName);
        wmsTransferDetail.setExecuteTime(currentDate);
        wmsTransferDetailMapper.insertWmsTransferDetail(wmsTransferDetail);


        wmsProductStockMapper.deleteWmsProductStockByProductStockId(productStock.getProductStockId());

        return 1;
    }

    /**
     * 转库入库，适合五楼半成品入成品库
     *
     * @param wmsTransferDetail
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int transferInstock(WmsTransferDetail wmsTransferDetail) {
        String userName = SecurityUtils.getUsername();
        Date currentDate = new Date();
        String targetLocationCode = wmsTransferDetail.getLocationCode();
        String materialBarcode = wmsTransferDetail.getMaterialBarcode();

        R<MesBaseBarcodeInfo> mesBaseBarcodeInfoR = remoteMesService.getBarcode(materialBarcode, SecurityConstants.INNER);
        if (mesBaseBarcodeInfoR == null) {
            throw new ServiceException("物料编码错误");
        }
        MesBaseBarcodeInfo mesBaseBarcodeInfo = mesBaseBarcodeInfoR.getData();
        if (mesBaseBarcodeInfo == null) {
            throw new ServiceException("物料编码错误");
        }

        WmsBaseLocation targetLocation = wmsBaseLocationMapper.selectWmsBaseLocationByLocationCode(targetLocationCode);
        if (targetLocation == null) {
            throw new ServiceException("库位不存在");
        }


        /**判断有没有已出库的转库记录*/
        WmsTransfer queryTransfer = new WmsTransfer();
        queryTransfer.setProductBatch(materialBarcode);
        queryTransfer.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_NOT_FINISH);
        List<WmsTransfer> wmsTransfers = wmsTransferMapper.selectWmsTransferList(queryTransfer);
        if (wmsTransfers == null || wmsTransfers.isEmpty()) {
            throw new ServiceException("没有此成品的转库出库记录，不能转库入库");
        }

        Long targetWarehouseId = targetLocation.getWarehouseId();
        WmsBaseWarehouse targetWarehouse = wmsBaseWarehouseMapper.selectWmsBaseWarehouseByWarehouseId(targetWarehouseId);

        WmsTransfer wmsTransfer = wmsTransfers.get(0);
        wmsTransfer.setTargetWarehouseId(targetWarehouseId);
        wmsTransfer.setTargetLocationCode(targetLocationCode);
        wmsTransfer.setInstockQty(BigDecimal.ONE);
        wmsTransfer.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_FINISH);
        wmsTransfer.setUpdateBy(userName);
        wmsTransfer.setUpdateDate(currentDate);
        wmsTransfer.setEndTime(currentDate);
        wmsTransferMapper.updateWmsTransfer(wmsTransfer);


        //插入转库任务明细
        wmsTransferDetail.setTransferId(wmsTransfer.getTransferId());
        wmsTransferDetail.setInstockBatch(materialBarcode);
        wmsTransferDetail.setMaterialId(mesBaseBarcodeInfo.getMaterialId());
        wmsTransferDetail.setRealAmount(BigDecimal.ONE);
        wmsTransferDetail.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_FINISH);
        wmsTransferDetail.setTransferDetailType(WmsConstants.WMS_TRANSFER_DETAIL_TYPE_INSTOCK);
        wmsTransferDetail.setCreateBy(userName);
        wmsTransferDetail.setCreateDate(currentDate);
        wmsTransferDetail.setExecutePerson(userName);
        wmsTransferDetail.setExecuteTime(currentDate);
        wmsTransferDetailMapper.insertWmsTransferDetail(wmsTransferDetail);


        //更新成品库存，一个成品一个条码，对应一条库存记录
        WmsProductStock productStock = new WmsProductStock();
        productStock.setTotalAmount(BigDecimal.ONE);
        productStock.setWarehouseId(targetWarehouseId);
        productStock.setLocationCode(targetLocationCode);
        productStock.setStockType(WmsConstants.PRODUCT_STOCK_STOCK_TYPE_PRODUCT);
        productStock.setProductBatch(materialBarcode);
        //            productStock.setQualityStatus();//todo: 获取质检状态
        productStock.setWarehouseFloor(targetWarehouse.getWarehouseFloor());
        productStock.setProductId(mesBaseBarcodeInfo.getMaterialId());
        productStock.setPlanCode(mesBaseBarcodeInfo.getPlanCode());
        productStock.setPlanDetailCode(mesBaseBarcodeInfo.getPlanDetailCode());
        productStock.setSaleOrderId(mesBaseBarcodeInfo.getSaleOrderId());
        productStock.setSaleorderCode(mesBaseBarcodeInfo.getSaleorderCode());
        productStock.setCreateDate(currentDate);
        productStock.setCreateBy(userName);
        wmsProductStockMapper.insertWmsProductStock(productStock);

        return 1;
    }


}
