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.domain.MesBaseBarcodeInfo;
import com.hw.wms.domain.*;
import com.hw.wms.domain.vo.WmsProductInstockVo;
import com.hw.wms.domain.vo.WmsRawInstockVo;
import com.hw.wms.mapper.WmsBaseLocationMapper;
import com.hw.wms.mapper.WmsProductInstockDetailMapper;
import com.hw.wms.mapper.WmsProductStockMapper;
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.mapper.WmsProductInstockMapper;
import com.hw.wms.service.IWmsProductInstockService;

/**
 * 成品入库记录;成品入库记录Service业务层处理
 *
 * @author xins
 * @date 2023-12-25
 */
@Service
public class WmsProductInstockServiceImpl implements IWmsProductInstockService {
    @Autowired
    private WmsProductInstockMapper wmsProductInstockMapper;

    @Autowired
    private WmsProductInstockDetailMapper wmsProductInstockDetailMapper;

    @Autowired
    private WmsProductStockMapper wmsProductStockMapper;


    @Autowired
    private WmsBaseLocationMapper wmsBaseLocationMapper;

    /**
     * 查询成品入库记录;成品入库记录
     *
     * @param productInstockId 成品入库记录;成品入库记录主键
     * @return 成品入库记录;成品入库记录
     */
    @Override
    public WmsProductInstock selectWmsProductInstockByProductInstockId(Long productInstockId) {
        return wmsProductInstockMapper.selectWmsProductInstockByProductInstockId(productInstockId);
    }

    /**
     * 查询成品入库记录;成品入库记录列表
     *
     * @param wmsProductInstock 成品入库记录;成品入库记录
     * @return 成品入库记录;成品入库记录
     */
    @Override
    public List<WmsProductInstock> selectWmsProductInstockList(WmsProductInstock wmsProductInstock) {
        return wmsProductInstockMapper.selectWmsProductInstockList(wmsProductInstock);
    }

    /**
     * 新增成品入库记录;成品入库记录
     *
     * @param wmsProductInstock 成品入库记录;成品入库记录
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertWmsProductInstock(WmsProductInstock wmsProductInstock) {
        int rows = wmsProductInstockMapper.insertWmsProductInstock(wmsProductInstock);
        insertWmsProductInstockDetail(wmsProductInstock);
        return rows;
    }

    /**
     * 修改成品入库记录;成品入库记录
     *
     * @param wmsProductInstock 成品入库记录;成品入库记录
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateWmsProductInstock(WmsProductInstock wmsProductInstock) {
        wmsProductInstockMapper.deleteWmsProductInstockDetailByProductInstockId(wmsProductInstock.getProductInstockId());
        insertWmsProductInstockDetail(wmsProductInstock);
        return wmsProductInstockMapper.updateWmsProductInstock(wmsProductInstock);
    }

    /**
     * 批量删除成品入库记录;成品入库记录
     *
     * @param productInstockIds 需要删除的成品入库记录;成品入库记录主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteWmsProductInstockByProductInstockIds(Long[] productInstockIds) {
        wmsProductInstockMapper.deleteWmsProductInstockDetailByProductInstockIds(productInstockIds);
        return wmsProductInstockMapper.deleteWmsProductInstockByProductInstockIds(productInstockIds);
    }

    /**
     * 删除成品入库记录;成品入库记录信息
     *
     * @param productInstockId 成品入库记录;成品入库记录主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteWmsProductInstockByProductInstockId(Long productInstockId) {
        wmsProductInstockMapper.deleteWmsProductInstockDetailByProductInstockId(productInstockId);
        return wmsProductInstockMapper.deleteWmsProductInstockByProductInstockId(productInstockId);
    }

    /**
     * 新增成品入库记录明细信息
     *
     * @param wmsProductInstock 成品入库记录;成品入库记录对象
     */
    public void insertWmsProductInstockDetail(WmsProductInstock wmsProductInstock) {
        List<WmsProductInstockDetail> wmsProductInstockDetailList = wmsProductInstock.getWmsProductInstockDetailList();
        Long productInstockId = wmsProductInstock.getProductInstockId();
        if (StringUtils.isNotNull(wmsProductInstockDetailList)) {
            List<WmsProductInstockDetail> list = new ArrayList<WmsProductInstockDetail>();
            for (WmsProductInstockDetail wmsProductInstockDetail : wmsProductInstockDetailList) {
                wmsProductInstockDetail.setProductInstockId(productInstockId);
                list.add(wmsProductInstockDetail);
            }
            if (list.size() > 0) {
                wmsProductInstockMapper.batchWmsProductInstockDetail(list);
            }
        }
    }


    /**
     * 新增成品入库记录(适用于移动手持端)
     *
     * @param wmsProductInstockVo 原材料入库记录
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertWmsProductInstock(WmsProductInstockVo wmsProductInstockVo) {
        String materialBarcode = wmsProductInstockVo.getMaterialBarcode();
        String productBatch = wmsProductInstockVo.getProductBatch();
        Long productId = wmsProductInstockVo.getProductId();

        String locationCode = wmsProductInstockVo.getLocationCode();
        WmsBaseLocation baseLocation = wmsBaseLocationMapper.selectWmsBaseLocationByLocationCode(locationCode);
        if (baseLocation == null) {
            throw new ServiceException("库位编码有误");
        }
        //todo 入库人权限判断;物料类型判断是否可以入此库位

        Date currentDate = new Date();
        String userName = SecurityUtils.getUsername();//todo 是否改成nickname
        WmsProductInstock wmsProductInstock = new WmsProductInstock();
        wmsProductInstock.setWarehouseId(baseLocation.getWarehouseId());
        wmsProductInstock.setLocationCode(locationCode);
        wmsProductInstock.setProductType(WmsConstants.PRODUCT_INSTOCK_STOCK_TYPE_PRODUCT);
        wmsProductInstock.setOperationType(WmsConstants.WMS_OPERATION_TYPE_MANUAL);
        wmsProductInstock.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_FINISH);
        wmsProductInstock.setPlanCode(wmsProductInstockVo.getPlanCode());
        wmsProductInstock.setPlanDetailCode(wmsProductInstockVo.getPlanDetailCode());
        wmsProductInstock.setInstockType(WmsConstants.PRODUCT_INSTOCK_INSTOCK_TYPE_PRODUCT);
        wmsProductInstock.setAuditStatus(WmsConstants.WMS_AUDIT_STATUS_PASS);
        wmsProductInstock.setApplyBy(userName);
        wmsProductInstock.setApplyDate(currentDate);

        //插入记录
        int rows = wmsProductInstockMapper.insertWmsProductInstock(wmsProductInstock);

        //插入明细
        insertWmsProductInstockDetail(wmsProductInstock, materialBarcode, productBatch, productId, wmsProductInstockVo);

        //更新库存
        updateProductStock(wmsProductInstock, wmsProductInstockVo, baseLocation,
                productBatch, productId, userName, currentDate);

        //todo：判断质检状态，同步erp
        return rows;
    }

    /**
     * 插入成品入库明细，手持成品入库使用。适用于4楼成品入库
     *
     * @param wmsProductInstock
     * @param materialBarcode
     * @param productBatch
     * @param productId
     * @param wmsProductInstockVo
     */
    public void insertWmsProductInstockDetail(WmsProductInstock wmsProductInstock, String materialBarcode, String productBatch, Long productId, WmsProductInstockVo wmsProductInstockVo) {
        WmsProductInstockDetail wmsProductInstockDetail = new WmsProductInstockDetail();
        wmsProductInstockDetail.setProductInstockId(wmsProductInstock.getProductInstockId());
        wmsProductInstockDetail.setLocationCode(wmsProductInstock.getLocationCode());
        wmsProductInstockDetail.setProductBarcode(materialBarcode);
        wmsProductInstockDetail.setProductBatch(productBatch);
        wmsProductInstockDetail.setProductId(productId);
        wmsProductInstockDetail.setExecuteStatus(WmsConstants.WMS_EXECUTE_STATUS_FINISH);
        wmsProductInstockDetail.setInstockBy(wmsProductInstock.getApplyBy());
        wmsProductInstockDetail.setInstockDate(wmsProductInstock.getApplyDate());
        wmsProductInstockDetail.setInstockWay(WmsConstants.PRODUCT_INSTOCK_INSTOCK_WAY_MANUAL);
        wmsProductInstockDetail.setPlanAmount(new BigDecimal(1));
        wmsProductInstockDetail.setInstockAmount(new BigDecimal(1));
        wmsProductInstockDetailMapper.insertWmsProductInstockDetail(wmsProductInstockDetail);
    }


    /**
     * 更新成品库存
     *
     * @param wmsProductInstock
     * @param wmsProductInstockVo
     * @param baseLocation
     * @param productBatch
     * @param productId
     * @param userName
     * @param currentDate
     */
    public void updateProductStock(WmsProductInstock wmsProductInstock, WmsProductInstockVo wmsProductInstockVo, WmsBaseLocation baseLocation,
                                   String productBatch, Long productId, String userName, Date currentDate) {
        String locationCode = wmsProductInstock.getLocationCode();
        BigDecimal instockAmount = new BigDecimal(1);
        //判断此库位的数量限制，是否还能入库
        WmsProductStock queryProductStock = new WmsProductStock();
        queryProductStock.setLocationCode(locationCode);
        BigDecimal totalAmount = wmsProductStockMapper.getProductStockTotalAmount(queryProductStock);
        totalAmount = totalAmount == null ? BigDecimal.ZERO : totalAmount;
        if (totalAmount.add(instockAmount).compareTo(baseLocation.getQtyLimit()) > 0) {
            throw new ServiceException("已超出库位数量限制，请重新选择库位");
        }

        //如果是同一库位入同一批次，则更新数量
        WmsProductStock wmsProductStock = wmsProductStockMapper.selectProductStockByLocationAndBatch(locationCode, productBatch);
        if (wmsProductStock != null) {
//            wmsProductStock.setQualityStatus(wmsRawInstockVo.getQualityStatus());
            wmsProductStock.setTotalAmount(wmsProductStock.getTotalAmount().add(instockAmount));
            wmsProductStock.setUpdateBy(userName);
            wmsProductStock.setUpdateDate(currentDate);
            wmsProductStockMapper.updateWmsProductStock(wmsProductStock);
        } else {
            wmsProductStock = new WmsProductStock();
            wmsProductStock.setWarehouseId(wmsProductInstock.getWarehouseId());
            wmsProductStock.setLocationCode(locationCode);
            wmsProductStock.setStockType(WmsConstants.PRODUCT_STOCK_STOCK_TYPE_PRODUCT);
            wmsProductStock.setProductId(productId);
            wmsProductStock.setProductBatch(productBatch);
            wmsProductStock.setPlanCode(wmsProductInstockVo.getPlanCode());
            wmsProductStock.setPlanDetailCode(wmsProductInstockVo.getPlanDetailCode());
//            wmsProductStock.setQualityStatus(wmsRawInstockVo.getQualityStatus());
            wmsProductStock.setTotalAmount(instockAmount);
            wmsProductStock.setCreateBy(userName);
            wmsProductStock.setCreateDate(currentDate);
            wmsProductStock.setInstockDate(currentDate);
            wmsProductStockMapper.insertWmsProductStock(wmsProductStock);
        }
    }

    public void syncToErp() {
        //todo 根据质检状态是通过的同步给ERP
    }

}
