package com.prolog.upcloud.base.wh.operate.convert;

import cn.hutool.core.util.StrUtil;
import com.prolog.cs.basic.warehouse.model.BaseWmsWarehouseMst;
import com.prolog.cs.basic.warehouse.model.vo.WarehouseLocatorBasicInfo;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.core.exception.BizException;
import com.prolog.upcloud.base.inventory.dto.DeviceContainerItemStockDTO;
import com.prolog.upcloud.base.inventory.vo.BatchNumberListVO;
import com.prolog.upcloud.base.wh.operate.model.WmsMoveD;
import com.prolog.upcloud.base.wh.operate.model.WmsMoveH;
import com.prolog.upcloud.base.wh.operate.model.WmsStereoD;
import com.prolog.upcloud.base.wh.operate.model.WmsStereoH;
import com.prolog.upcloud.base.wh.operate.vo.*;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

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

@Mapper(componentModel = "spring")
public interface MoveConvert {


    @Mapping(target = "dcId", source = "warehouse.dcId")
    @Mapping(target = "moveBillType", expression = "java(com.prolog.upcloud.base.wh.operate.enums.WmsMoveBillType.WMS.name())")
    @Mapping(target = "subBillType", expression = "java(com.prolog.upcloud.base.wh.operate.enums.WmsMoveSubBillType.MOVE_LOCATION.getType())")
    @Mapping(target = "moveHeaderId", source = "snowId")
    @Mapping(target = "autoBillNum", source = "snowId")
    @Mapping(target = "status", expression = "java(com.prolog.upcloud.base.wh.operate.enums.WmsMoveStatus.NEW.getStatus())")
    @Mapping(target = "accessLevel", expression = "java(com.prolog.upcloud.base.wh.operate.enums.WmsAccessLevel.ALL.getCode())")
    @Mapping(target = "moveDate", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "cargoOwnerId", source = "vo.cargoOwnerId")
    @Mapping(target = "warehouseId", source = "vo.warehouseId")
    @Mapping(target = "customBillNum", source = "vo.customBillNum")
    @Mapping(target = "moveInBldg", source = "vo.moveInBldg")
    @Mapping(target = "moveOutBldg", source = "vo.moveOutBldg")
    @Mapping(target = "comments", source = "vo.comments")
    @Mapping(target = "departmentId", source = "vo.departmentId")
    @Mapping(target = "enterpriseId", source = "user.enterpriseId")
    @Mapping(target = "gmtCreate", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "creator", source = "user.id")
    @Mapping(target = "creatorName", source = "user.nickname")
    @Mapping(target = "gmtModified", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "modifier", source = "user.id")
    @Mapping(target = "modifierName", source = "user.nickname")
    @Mapping(target = "printCount", expression = "java(0L)")
    WmsMoveH generateMoveHdr4saveMoveLocatorInfo(WmsMoveSaveVO vo, UserDTO user, BaseWmsWarehouseMst warehouse, String snowId);

    @Mapping(target = "dcId", source = "warehouse.dcId")
    @Mapping(target = "warehouseId", source = "warehouse.warehouseId")
    @Mapping(target = "moveBillType", expression = "java(com.prolog.upcloud.base.wh.operate.enums.WmsMoveBillType.WMS.name())")
    @Mapping(target = "subBillType", expression = "java(com.prolog.upcloud.base.wh.operate.enums.WmsMoveSubBillType.MOVE_LOCATION.getType())")
    @Mapping(target = "moveHeaderId", source = "snowId")
    @Mapping(target = "autoBillNum", source = "snowId")
    @Mapping(target = "status", expression = "java(com.prolog.upcloud.base.wh.operate.enums.WmsMoveStatus.NEW.getStatus())")
    @Mapping(target = "accessLevel", expression = "java(com.prolog.upcloud.base.wh.operate.enums.WmsAccessLevel.ALL.getCode())")
    @Mapping(target = "moveDate", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "enterpriseId", source = "user.enterpriseId")
    @Mapping(target = "gmtCreate", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "creator", source = "user.id")
    @Mapping(target = "creatorName", source = "user.nickname")
    @Mapping(target = "gmtModified", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "modifier", source = "user.id")
    @Mapping(target = "modifierName", source = "user.nickname")
    @Mapping(target = "printCount", expression = "java(0L)")
    @Mapping(target = "cargoOwnerId", source = "cargoOwnerId")
    WmsMoveH generateMoveHdr4saveMoveLocatorInfoByPda(WmsMovePdaSaveVO vo, UserDTO user, com.prolog.upcloud.base.wh.operate.out.WarehouseLocatorBasicInfo warehouse, String snowId, String cargoOwnerId);


    @Mapping(target = "moveHeaderId", source = "moveH.moveHeaderId")
    @Mapping(target = "conversionRate", source = "detailVO.conversionRate", defaultExpression = "java(java.math.BigDecimal.ONE)")
    @Mapping(target = "quantity", source = "detailVO.caseQuantity")
    @Mapping(target = "pieceQuantity", expression = "java(detailVO.getCaseQuantity().multiply(detailVO.getCaseConversionRate()).add(detailVO.getOddPieceQuantity()))")
    @Mapping(target = "warehouseWorkerId", source = "saveVO.warehouseWorkerId")
    @Mapping(target = "status", expression = "java(com.prolog.upcloud.base.wh.operate.enums.WmsMoveDStatus.NEW.getStatus())")
    @Mapping(target = "enterpriseId", source = "user.enterpriseId")
    @Mapping(target = "gmtCreate", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "creator", source = "user.id")
    @Mapping(target = "creatorName", source = "user.nickname")
    @Mapping(target = "gmtModified", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "modifier", source = "user.id")
    @Mapping(target = "modifierName", source = "user.nickname")
    @Mapping(target = "inPickMode", expression = "java(getInPickMode(list,detailVO))")
    @Mapping(target = "outPickMode", expression = "java(getOutPickMode(list,detailVO))")
    @Mapping(target = "itemId", source = "detailVO.itemId")
    @Mapping(target = "outLocatorId", source = "detailVO.outLocatorId")
    @Mapping(target = "outContainerCode", source = "detailVO.outContainerCode")
    @Mapping(target = "inLocatorId", source = "detailVO.inLocatorId")
    @Mapping(target = "inContainerCode", source = "detailVO.inContainerCode")
    @Mapping(target = "outGoodsCaseCode", source = "detailVO.outGoodsCaseCode")
    @Mapping(target = "inGoodsCaseCode", source = "detailVO.inGoodsCaseCode")
    @Mapping(target = "moveLineId", ignore = true)
    @Mapping(target = "comments", source = "saveVO.comments")
    @Mapping(target = "uom", source = "detailVO.uom")
    @Mapping(target = "batchId", source = "detailVO.batchId")
    @Mapping(target = "batchNum", source = "detailVO.batchNum")
    @Mapping(target = "reason", source = "detailVO.reason")
    @Mapping(target = "oddPieceQuantity", source = "detailVO.oddPieceQuantity")
    @Mapping(target = "caseConversionRate", source = "detailVO.caseConversionRate")
    @Mapping(target = "inStockStatus", source = "detailVO.inStockStatus")
    @Mapping(target = "outStockStatus", source = "detailVO.outStockStatus")
    @Mapping(target = "erpPlanQuantity", source = "detailVO.erpPlanQuantity")
    @Mapping(target = "erpReason", source = "detailVO.erpReason")
    @Mapping(target = "unqualifiedReason", source = "detailVO.unqualifiedReason")
    @Mapping(target = "moveOutBldg", source = "saveVO.moveOutBldg")
    @Mapping(target = "moveInBldg", source = "saveVO.moveInBldg")
    @Mapping(target = "inStockSubStatus", constant = "1")
    WmsMoveD generateMoveDtl4saveMoveLocatorInfo(WmsMoveDetailVO detailVO, WmsMoveSaveVO saveVO, UserDTO user, List<WarehouseLocatorBasicInfo> list, WmsMoveH moveH);

    @Mapping(target = "moveHeaderId", source = "hdrId")
    @Mapping(target = "conversionRate", source = "batch.caseConversionRate", defaultExpression = "java(java.math.BigDecimal.ONE)")
    @Mapping(target = "quantity", source = "detailVO.caseQuantity")
    @Mapping(target = "pieceQuantity", expression = "java(detailVO.getCaseQuantity().multiply(batch.getCaseConversionRate()).add(detailVO.getOddPieceQuantity()))")
    @Mapping(target = "status", expression = "java(com.prolog.upcloud.base.wh.operate.enums.WmsMoveDStatus.NEW.getStatus())")
    @Mapping(target = "enterpriseId", source = "user.enterpriseId")
    @Mapping(target = "gmtCreate", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "creator", source = "user.id")
    @Mapping(target = "creatorName", source = "user.nickname")
    @Mapping(target = "gmtModified", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "modifier", source = "user.id")
    @Mapping(target = "modifierName", source = "user.nickname")
    @Mapping(target = "inPickMode", source = "inLocator.pickMode")
    @Mapping(target = "outPickMode", source = "outLocator.pickMode")
    @Mapping(target = "itemId", source = "batch.itemId")
    @Mapping(target = "outLocatorId", source = "outLocator.warehouseLocatorId")
    @Mapping(target = "outContainerCode", source = "saveVO.outContainerCode")
    @Mapping(target = "inLocatorId", source = "inLocator.warehouseLocatorId")
    @Mapping(target = "inContainerCode", source = "saveVO.inContainerCode")
    @Mapping(target = "uom", source = "batch.caseUom")
    @Mapping(target = "batchId", source = "batch.batchId")
    @Mapping(target = "batchNum", source = "batch.batchNum")
    @Mapping(target = "oddPieceQuantity", source = "detailVO.oddPieceQuantity")
    @Mapping(target = "caseConversionRate", source = "batch.caseConversionRate")
    @Mapping(target = "inStockStatus", source = "detailVO.stockStatus")
    @Mapping(target = "outStockStatus", source = "detailVO.stockStatus")
    WmsMoveD generateMoveDtl4saveMoveLocatorInfo4Pda(WmsMovePdaSaveVO saveVO, WmsMovePdaDetailVO detailVO, UserDTO user, com.prolog.upcloud.base.wh.operate.out.WarehouseLocatorBasicInfo inLocator, com.prolog.upcloud.base.wh.operate.out.WarehouseLocatorBasicInfo outLocator, String hdrId, BatchNumberListVO batch);

    default String getInPickMode(List<WarehouseLocatorBasicInfo> list, WmsMoveDetailVO detailVO) {
        String inLocatorId = detailVO.getInLocatorId();
        WarehouseLocatorBasicInfo inLocator = list.stream().filter(x -> x.getWarehouseLocatorId().equals(inLocatorId)).findFirst().orElse(null);
        if (inLocator == null) {
            throw new BizException("移入库位不存在或已失效");
        }

        String inWarehouseAreaCategory = inLocator.getWarehouseAreaCategory();

        if (StrUtil.isNotEmpty(inWarehouseAreaCategory) && "ZJK".equals(inWarehouseAreaCategory)) {
            BigDecimal oddPieceQuantity = detailVO.getOddPieceQuantity();
            if (oddPieceQuantity != null && oddPieceQuantity.compareTo(BigDecimal.ZERO) != 0) {
                throw new BizException("移入库位的货位为整件,请检查的自己的移动数量是否是个整件!");
            }
        }

        return inLocator.getPickMode();
    }

    default String getOutPickMode(List<WarehouseLocatorBasicInfo> list, WmsMoveDetailVO detailVO) {
        String outLocatorId = detailVO.getOutLocatorId();
        WarehouseLocatorBasicInfo outLocator = list.stream().filter(x -> x.getWarehouseLocatorId().equals(outLocatorId)).findFirst().orElse(null);
        if (outLocator == null) {
            throw new BizException("移出库位不存在或已失效");
        }

        String outWarehouseAreaCategory = outLocator.getWarehouseAreaCategory();
        if (StrUtil.isNotEmpty(outWarehouseAreaCategory) && "ZJK".equals(outWarehouseAreaCategory)) {
            BigDecimal oddPieceQuantity = detailVO.getOddPieceQuantity();
            if (oddPieceQuantity != null && oddPieceQuantity.compareTo(BigDecimal.ZERO) != 0) {
                throw new BizException("移出库位的货位为整件,请检查的自己的移动数量是否是个整件!");
            }
        }
        return outLocator.getPickMode();
    }


    @Mapping(target = "enterpriseId", source = "user.enterpriseId")
    @Mapping(target = "headerId", expression = "java(com.prolog.upcloud.base.wh.operate.utils.IdUtil.getId(com.prolog.upcloud.base.wh.operate.constant.BillNoConstant.STEREO_HEADER_ID))")
    @Mapping(target = "warehouseId", source = "vo.warehouseId")
    @Mapping(target = "containerCode", source = "vo.containerCode")
    @Mapping(target = "cargoOwnerId", source = "vo.cargoOwnerId")
    @Mapping(target = "cargoOwnerName", source = "vo.cargoOwnerName")
    @Mapping(target = "locatorCode", source = "vo.locatorCode")
    @Mapping(target = "locatorId", source = "vo.locatorId")
    @Mapping(target = "gmtCreate", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "creator", source = "user.id")
    @Mapping(target = "creatorName", source = "user.nickname")
    @Mapping(target = "gmtModified", expression = "java(cn.hutool.core.date.DateUtil.date())")
    @Mapping(target = "modifier", source = "user.id")
    @Mapping(target = "modifierName", source = "user.nickname")
    @Mapping(target = "status", expression = "java(com.prolog.upcloud.base.wh.operate.enums.StereoHStatus.INITIALIZATION.getCode())")
    WmsStereoH generateStereoH(MoveStereoAddVO vo, UserDTO user);

    @Mapping(target = "cargoOwnerId", source = "h.cargoOwnerId")
    @Mapping(target = "itemId", source = "t.itemId")
    @Mapping(target = "itemCode", source = "t.itemCode")
    @Mapping(target = "itemName", source = "t.itemName")
    @Mapping(target = "batchId", source = "t.batchId")
    @Mapping(target = "batchNum", source = "t.batchNum")
    @Mapping(target = "quantity", source = "t.quantity")
    @Mapping(target = "uom", source = "t.packUnits")
    @Mapping(target = "headerId", source = "h.headerId")
    @Mapping(target = "manufacturerLotNum", source = "t.manufacturerLotNum")
    @Mapping(target = "stockStatus", source = "t.status")
    @Mapping(target = "outboundInstruct", expression = "java(com.prolog.upcloud.base.wh.operate.constant.EisConstant.OUTBOUND_INSTRUCT_UN_DELIVERY)")
    @Mapping(target = "gmtCreate", source = "h.gmtCreate")
    @Mapping(target = "creator", source = "h.creator")
    @Mapping(target = "creatorName", source = "h.creatorName")
    @Mapping(target = "gmtModified", source = "h.gmtModified")
    @Mapping(target = "modifier", source = "h.modifier")
    @Mapping(target = "modifierName", source = "h.modifierName")
    @Mapping(target = "status", expression = "java(com.prolog.upcloud.base.wh.operate.enums.StereoDStatus.INITIALIZATION.getCode())")
    @Mapping(target = "isDeleted", expression = "java(0)")
    @Mapping(target = "lockStockLotId", source = "t.id")
    WmsStereoD generateStereoD(DeviceContainerItemStockDTO t, WmsStereoH h);

    com.prolog.upcloud.base.wh.operate.out.WarehouseLocatorBasicInfo copyWarehouseLocatorBasicInfo(WarehouseLocatorBasicInfo locator);

    @Mapping(target = "detailId", ignore = true)
    WmsStereoD copyWmsStereoD(WmsStereoD srcStereoD);
}
