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.security.utils.SecurityUtils;
import com.hw.mes.api.RemoteMesService;
import com.hw.mes.api.domain.MesBaseBarcodeInfo;
import com.hw.wms.domain.WmsBaseLocation;
import com.hw.wms.domain.WmsProductStock;
import com.hw.wms.mapper.WmsBaseLocationMapper;
import com.hw.wms.mapper.WmsProductStockMapper;
import com.hw.wms.mapper.WmsTransferDetailMapper;
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.domain.WmsTransferDetail;
import com.hw.wms.mapper.WmsTransferMapper;
import com.hw.wms.domain.WmsTransfer;
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;

    @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 locationCode = 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("物料编码错误");
        }

        String productBatch = mesBaseBarcodeInfo.getBatchCode();

        Long transferId = wmsTransferDetail.getTransferId();
        WmsTransfer wmsTransfer;

        if (transferId == null) {
            WmsTransfer queryTransfer = new WmsTransfer();
            queryTransfer.setOriLocationCode(locationCode);
            queryTransfer.setProductBatch(productBatch);
            queryTransfer.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_NOT_FINISH);
            List<WmsTransfer> wmsTransfers = wmsTransferMapper.selectWmsTransferList(queryTransfer);
            if (wmsTransfers == null || wmsTransfers.isEmpty()) {
                throw new ServiceException("没有此任务");
            }
            if (wmsTransfers.size() > 1) {
                throw new ServiceException("有多条此库位任务，请选择具体任务后点击出库");
            }

            wmsTransfer = wmsTransfers.get(0);
        } else {
            wmsTransfer = wmsTransferMapper.selectWmsTransferByTransferId(transferId);
        }

        BigDecimal applyQty = wmsTransfer.getApplyQty();
        BigDecimal outstockQty = wmsTransfer.getOutstockQty() == null ? BigDecimal.ZERO : wmsTransfer.getOutstockQty();
        BigDecimal currentOutstockQty = outstockQty.add(BigDecimal.ONE);
        if (applyQty.compareTo(currentOutstockQty) < 0) {
            throw new ServiceException("已出库完成，不能多次出库");
        }

        //插入转库任务明细
        wmsTransferDetail.setTransferId(wmsTransfer.getTransferId());
        wmsTransferDetail.setInstockBatch(productBatch);
        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);

        //更新转库任务
        wmsTransfer.setOutstockQty(currentOutstockQty);
        wmsTransfer.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_EXECUTING);
        wmsTransfer.setUpdateDate(currentDate);
        wmsTransfer.setUpdateBy(userName);
        wmsTransferMapper.updateWmsTransfer(wmsTransfer);

        //更新成品库存
        WmsProductStock productStock = wmsProductStockMapper.selectProductStockByLocationAndBatch(locationCode, productBatch,WmsConstants.PRODUCT_STOCK_STOCK_TYPE_SEMI);
        productStock.setTotalAmount(productStock.getTotalAmount().subtract(BigDecimal.ONE));
        productStock.setOccupyAmount(productStock.getOccupyAmount().subtract(BigDecimal.ONE));
        productStock.setUpdateDate(currentDate);
        productStock.setUpdateBy(userName);
        wmsProductStockMapper.updateWmsProductStock(productStock);

        return 1;
    }

    /**
     * 转库入库，适合五楼半成品入成品库
     *
     * @param wmsTransferDetail
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int transferInstock(WmsTransferDetail wmsTransferDetail) {
        String userName = SecurityUtils.getUsername();
        Date currentDate = new Date();
        String locationCode = 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("物料编码错误");
        }
        String productBatch = mesBaseBarcodeInfo.getBatchCode();

        WmsBaseLocation location = wmsBaseLocationMapper.selectWmsBaseLocationByLocationCode(locationCode);
        Long warehouseId = location.getWarehouseId();

        Long transferId = wmsTransferDetail.getTransferId();
        WmsTransfer wmsTransfer;
        if (transferId == null) {
            WmsTransfer queryTransfer = new WmsTransfer();
            queryTransfer.setTargetWarehouseId(warehouseId);
            queryTransfer.setProductBatch(productBatch);
            queryTransfer.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_EXECUTING);
            List<WmsTransfer> wmsTransfers = wmsTransferMapper.selectWmsTransferList(queryTransfer);
            if (wmsTransfers == null || wmsTransfers.isEmpty()) {
                throw new ServiceException("没有此任务或者还未出库");
            }
            if (wmsTransfers.size() > 1) {
                throw new ServiceException("有多条此库位任务，请选择具体任务后点击出库");
            }

            wmsTransfer = wmsTransfers.get(0);
        } else {
            wmsTransfer = wmsTransferMapper.selectWmsTransferByTransferId(transferId);
        }

        BigDecimal applyQty = wmsTransfer.getApplyQty();
        BigDecimal outstockQty = wmsTransfer.getOutstockQty() == null ? BigDecimal.ZERO : wmsTransfer.getOutstockQty();
        BigDecimal instockQty = wmsTransfer.getInstockQty();
        BigDecimal currentInstockQty = instockQty.add(BigDecimal.ONE);

        if (outstockQty.compareTo(currentInstockQty) < 0) {
            throw new ServiceException("请先出库再入库");
        }

        //插入转库任务明细
        wmsTransferDetail.setTransferId(wmsTransfer.getTransferId());
        wmsTransferDetail.setInstockBatch(productBatch);
        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);

        //更新转库任务
        wmsTransfer.setInstockQty(currentInstockQty);
        if (applyQty.compareTo(currentInstockQty) == 0) {//出库和入库都已完成
            wmsTransfer.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_FINISH);
        }

        wmsTransfer.setUpdateDate(currentDate);
        wmsTransfer.setUpdateBy(userName);
        wmsTransferMapper.updateWmsTransfer(wmsTransfer);

        //更新成品库存
        WmsProductStock productStock = wmsProductStockMapper.selectProductStockByLocationAndBatch(locationCode, productBatch,WmsConstants.PRODUCT_STOCK_STOCK_TYPE_PRODUCT);
        if (productStock == null) {
            productStock = new WmsProductStock();
            productStock.setTotalAmount(BigDecimal.ONE);
            productStock.setWarehouseId(warehouseId);
            productStock.setLocationCode(locationCode);
            productStock.setStockType(WmsConstants.PRODUCT_STOCK_STOCK_TYPE_PRODUCT);
            productStock.setProductBatch(productBatch);
            //            productStock.setQualityStatus();//todo: 获取质检状态
            productStock.setProductId(mesBaseBarcodeInfo.getMaterialId());
            productStock.setPlanCode(mesBaseBarcodeInfo.getPlanCode());
            productStock.setPlanDetailCode(mesBaseBarcodeInfo.getPlanDetailCode());
            productStock.setSaleorderCode(mesBaseBarcodeInfo.getSaleorderCode());
            productStock.setCreateDate(currentDate);
            productStock.setCreateBy(userName);
            wmsProductStockMapper.insertWmsProductStock(productStock);
        } else {
            productStock.setTotalAmount(productStock.getTotalAmount().add(BigDecimal.ONE));
            productStock.setUpdateDate(currentDate);
            productStock.setUpdateBy(userName);
            wmsProductStockMapper.updateWmsProductStock(productStock);
        }


        //TODO:同步ERP库存
        return 1;
    }


}
