package cn.iocoder.yudao.module.system.dal.mysql.houselocation;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationItemRespVO;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationRespVO;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Set;

/**
 * 库位 Mapper
 *
 * @author 陈宾顺
 */
@Mapper
public interface WareHouseLocationMapper extends BaseMapperX<WareHouseLocationDO> {

    default PageResult<WareHouseLocationDO> selectPage(WareHouseLocationPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<WareHouseLocationDO>()
                .eqIfPresent(WareHouseLocationDO::getLaneId, reqVO.getLaneId())
                .likeIfPresent(WareHouseLocationDO::getLaneName, reqVO.getLaneName())
                .eqIfPresent(WareHouseLocationDO::getAreaId, reqVO.getAreaId())
                .likeIfPresent(WareHouseLocationDO::getAreaName, reqVO.getAreaName())
                .likeIfPresent(WareHouseLocationDO::getLocationNo, reqVO.getLocationNo())
                .likeIfPresent(WareHouseLocationDO::getGroupName, reqVO.getGroupName())
                .eqIfPresent(WareHouseLocationDO::getLocationYaw, reqVO.getLocationYaw())
                .likeIfPresent(WareHouseLocationDO::getSkuInfo, reqVO.getSkuInfo())
                .eqIfPresent(WareHouseLocationDO::getSkuBatch, reqVO.getSkuBatch())
                .eqIfPresent(WareHouseLocationDO::getSkuNumber, reqVO.getSkuNumber())
                .eqIfPresent(WareHouseLocationDO::getTrayInfo, reqVO.getTrayInfo())
                .eqIfPresent(WareHouseLocationDO::getLocationEnable, reqVO.getLocationEnable())
                .eqIfPresent(WareHouseLocationDO::getLocationLock, reqVO.getLocationLock())
                .eqIfPresent(WareHouseLocationDO::getLocationUseStatus, reqVO.getLocationUseStatus())
                .eqIfPresent(WareHouseLocationDO::getLocationX, reqVO.getLocationX())
                .eqIfPresent(WareHouseLocationDO::getLocationY, reqVO.getLocationY())
                .eqIfPresent(WareHouseLocationDO::getLocationWide, reqVO.getLocationWide())
                .eqIfPresent(WareHouseLocationDO::getLocationDeep, reqVO.getLocationDeep())
                .eqIfPresent(WareHouseLocationDO::getLocationHeight, reqVO.getLocationHeight())
                .eqIfPresent(WareHouseLocationDO::getLocationDefaultHeight, reqVO.getLocationDefaultHeight())
                .eqIfPresent(WareHouseLocationDO::getLocationTotalHeight, reqVO.getLocationTotalHeight())
                .eqIfPresent(WareHouseLocationDO::getLocationTrayHeight, reqVO.getLocationTrayHeight())
                .eqIfPresent(WareHouseLocationDO::getLocationStorey, reqVO.getLocationStorey())
                .eqIfPresent(WareHouseLocationDO::getLocationType, reqVO.getLocationType())
                .eqIfPresent(WareHouseLocationDO::getLocationNumber, reqVO.getLocationNumber())
                .eqIfPresent(WareHouseLocationDO::getTaskId, reqVO.getTaskId())
                .eqIfPresent(WareHouseLocationDO::getMapId, reqVO.getMapId())
                .betweenIfPresent(WareHouseLocationDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(WareHouseLocationDO::getId));
    }

    /**
     * 查询空闲的库位id
     * @param type 类型（1：库位、2：线库、 3：区域）
     * @param id 库位/线库/区域
     * @return
     */
    WareHouseLocationDO selectByTypeAndId(@Param("locationUseStatus") Integer locationUseStatus,
                           @Param("takeType") Integer takeType,
                           @Param("id")  Long id,
                           @Param("locationIds") List<Long> locationIds,
                           @Param("mapIds") Set<Long> mapIds,
                           @Param("takeMapItemIds") List<Long> takeMapItemIds,
                           @Param("laneIds") List<Long> laneIds,
                           @Param("areaIds") List<Long> areaIds);

    /**
     * 普通查询(未删除)
     * @param wareHouseLocationDO
     * @return
     */
    WareHouseLocationDO queryAllByLimit(WareHouseLocationDO wareHouseLocationDO);


    /**
     * 查询库位
     * (注意:----------不能修改排序-----------------)
     */
    List<WareHouseLocationDO> selectLocations(@Param("query") WareHouseLocationDO query,
                                              @Param("locationIds") List<Long> locationIds,
                                              @Param("mapIds")  Set<Long> mapIds,
                                              @Param("laneIds") List<Long> laneIds,
                                              @Param("areaIds") List<Long> areaIds,
                                              @Param("mapItemIds") List<Long> mapItemIds);

    void updateLocationLockList( @Param("locationIds") List<Long> locationIds,
                                 @Param("taskId") Long taskId,
                                 @Param("locationLock") Integer locationLock);

    /**
     * 根据类型查库位/线库/区域
     * @param requestVO
     * @return
     */
    List<WareHouseLocationRespVO> getLocationByName(WareHouseLocationVO requestVO);

    /**
     * 查询相通的线库 且 有货的 排序的位置较小的库位
     * @param locations
     * @return
     */
    List<WareHouseLocationDO> selectLocationByList(@Param("locations") List<WareHouseLocationDO> locations);

    /**
     * 查询需要移库的库位
     * @param locationIds
     * @return
     */
    List<WareHouseLocationDO> selectNeedMoveLocation(@Param("locationIds") Set<Long> locationIds);

    /**
     * 更新
     * @param wareHouseLocationDO
     */
    void updateEntity(WareHouseLocationDO wareHouseLocationDO);

    void releaseLocationLockList(@Param("locationIds") List<Long> locationIds,
                                 @Param("taskId") Long taskId,
                                 @Param("locationLock") Integer locationLock);

    /**
     * 更新线库名称
     * @param laneId
     * @param laneName
     */
    void updateLocationLaneNameByLaneId(@Param("laneId") Long laneId,
                                        @Param("laneName") String laneName);

    /**
     * 设置库位的线库id和名称为空
     * @param laneId
     */
    void updateLocationLaneNameEmptyByLaneId(@Param("laneId") Long laneId);

    /**
     * 设置库位的区域id和名称为空
     * @param areaId
     */
    void updateLocationAreaNameEmptyByAreaId(@Param("areaId") Long areaId);

    /**
     * 查询此库位的上层, 是否有货
     * @param mapItemId
     * @param locationStorey
     * @return
     */
    List<Long> queryUpperLevelsByMapItemId(@Param("mapItemId") Long mapItemId,
                                                          @Param("locationStorey") Integer locationStorey);

    /**
     * 查询此库位的下层，是否没货
     * @param mapItemId
     * @param locationStorey
     * @return
     */
    List<Long> queryLowerLevelsByMapItemId(@Param("mapItemId") Long mapItemId,
                                                          @Param("locationStorey") Integer locationStorey);

    /**
     * 获取这个地图对应的库位和坐标信息
     * @param mapId
     * @return
     */
    List<WareHouseLocationItemRespVO> getLocationsXYByMapId(@Param("mapId") Long mapId);

    /**
     * 根据地图id删除
     * @param mapId
     */
    void deleteHouseLocationByMapId(@Param("mapId") Long mapId);

    /**
     * 查询有货或者有锁定的库位
     * @param mapId
     * @return
     */
    List<WareHouseLocationDO> getInStockLockLocationByMapId(@Param("mapId") Long mapId);
}
