package com.cf.imes.module.executor.dal.mysql.plate;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cf.imes.framework.common.enums.OrderPlateCutStatusEnum;
import com.cf.imes.framework.common.enums.OrderPlateTypeEnum;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.module.executor.controller.admin.manage.pack.vo.PlateDetailsRespVO;
import com.cf.imes.module.executor.controller.admin.manage.process.vo.PlateDetails;
import com.cf.imes.module.executor.controller.admin.manage.query.vo.pack.PackageDetailsRespVO;
import com.cf.imes.module.executor.controller.admin.order.vo.order.LabelOrderPlateData;
import com.cf.imes.module.executor.controller.admin.plan.saveOptimize.PrintOrderPackReqVO;
import com.cf.imes.module.executor.controller.admin.plate.vo.NoPlanPlatePageReqVO;
import com.cf.imes.module.executor.controller.admin.plate.vo.PlateGoodsIdVO;
import com.cf.imes.module.executor.controller.admin.plate.vo.PlateGoodsRespVO;
import com.cf.imes.module.executor.controller.admin.plate.vo.PlatePageReqVO;
import com.cf.imes.module.executor.controller.admin.plate.vo.PlateRespVO;
import com.cf.imes.module.executor.dal.dataobject.orderItem.OrdersViewPlatesPageDO;
import com.cf.imes.module.executor.dal.dataobject.plate.PlateDO;
import com.cf.imes.module.executor.dal.dataobject.plate.PlateDetailDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getUserOrganId;

/**
 * 订单板件 Mapper
 *
 * @author 晨丰科技
 */
@Mapper
public interface PlateMapper extends BaseMapperX<PlateDO> {

    default PageResult<PlateDO> selectPage(PlatePageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId,getUserOrganId())
                .eqIfPresent(PlateDO::getOrderId, reqVO.getOrderId())
                .likeIfPresent(PlateDO::getName, reqVO.getName())
                .eqIfPresent(PlateDO::getType, reqVO.getType())
                .eqIfPresent(PlateDO::getGoodsId, reqVO.getGoodsId())
                .eqIfPresent(PlateDO::getWidth, reqVO.getWidth())
                .eqIfPresent(PlateDO::getHeight, reqVO.getHeight())
                .eqIfPresent(PlateDO::getThickness, reqVO.getThickness())
                .eqIfPresent(PlateDO::getSplitWidth, reqVO.getSplitWidth())
                .eqIfPresent(PlateDO::getSplitHeight, reqVO.getSplitHeight())
                .eqIfPresent(PlateDO::getSplitThickness, reqVO.getSplitThickness())
                .eqIfPresent(PlateDO::getSealLeft, reqVO.getSealLeft())
                .eqIfPresent(PlateDO::getSealRight, reqVO.getSealRight())
                .eqIfPresent(PlateDO::getSealUp, reqVO.getSealUp())
                .eqIfPresent(PlateDO::getSealDown, reqVO.getSealDown())
                .eqIfPresent(PlateDO::getArea, reqVO.getArea())
                .eqIfPresent(PlateDO::getTexture, reqVO.getTexture())
                .eqIfPresent(PlateDO::getHoleFace, reqVO.getHoleFace())
                .eqIfPresent(PlateDO::getHoleArrange, reqVO.getHoleArrange())
                .eqIfPresent(PlateDO::getUnregularPointCount, reqVO.getUnregularPointCount())
                .eqIfPresent(PlateDO::getFrontHoleCount, reqVO.getFrontHoleCount())
                .eqIfPresent(PlateDO::getBackHoleCount, reqVO.getBackHoleCount())
                .eqIfPresent(PlateDO::getSideHoleCount, reqVO.getSideHoleCount())
                .eqIfPresent(PlateDO::getFrontModelCount, reqVO.getFrontModelCount())
                .eqIfPresent(PlateDO::getBackModelCount, reqVO.getBackModelCount())
                .eqIfPresent(PlateDO::getIsDoor, reqVO.getIsDoor())
                .eqIfPresent(PlateDO::getOpenDoorType, reqVO.getOpenDoorType())
                .eqIfPresent(PlateDO::getOffsetX, reqVO.getOffsetX())
                .eqIfPresent(PlateDO::getOffsetY, reqVO.getOffsetY())
                .eqIfPresent(PlateDO::getIsArcAcross, reqVO.getIsArcAcross())
                .eqIfPresent(PlateDO::getModuleTypeId, reqVO.getModuleTypeId())
                .eqIfPresent(PlateDO::getFilterType, reqVO.getFilterType())
                .eqIfPresent(PlateDO::getRemark, reqVO.getRemark())
                .betweenIfPresent(PlateDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(PlateDO::getId));
    }


    IPage<PlateRespVO> selectProductList(@Param("page") IPage<PlateRespVO> page , @Param("orderId")Long orderId, @Param("roomId")Long roomId , @Param("bodyId")Long bodyId,@Param("organId") Long organId);


    List<PlateGoodsRespVO> selectPlateGoodsList(@Param("orderId") Long orderId, @Param("organId") Long organId, @Param("deleted") Integer deleted); // 明细

    List<PlateGoodsRespVO> selectPlateGoodsListSummary(@Param("orderId") Long orderId, @Param("organId") Long organId, @Param("deleted") Integer deleted); // 汇总


    // 单个修改删除状态
    default int updateOrderDeleted(Long id, Integer deleted, Long organId) {
        LambdaUpdateWrapper<PlateDO> wrapper = new LambdaUpdateWrapper<PlateDO>()
                .set(PlateDO::getDeleted, deleted)
                .eq(PlateDO::getOrderId, id)
                .eq(PlateDO::getOrganId, organId);
        if (deleted == 0)
            wrapper.eq(PlateDO::getDeleted, 1);
        return update(wrapper);
    }

    void updateDeletedById(@Param("plateIds") List<Long> plateIds, @Param("deleted") Integer deleted, @Param("organId") Long organId, @Param("orderId") Long orderId);

    /**
     * 删除小板，重置开料状态
     *
     * @param plateIds
     * @param organId
     * @param orderId
     */
    void updateDeletedPlate(@Param("plateIds") List<Long> plateIds, @Param("organId") Long organId, @Param("orderId") Long orderId);

    /**
     * 恢复小板，重置开料状态
     * @param plateIds
     * @param organId
     * @param orderId
     */
    void updateNoDeletedPlate(@Param("plateIds") List<Long> plateIds, @Param("organId") Long organId, @Param("orderId") Long orderId);

    int countPlateByOrderId(@Param("orderId") Long orderId, @Param("organId") Long organId, @Param("deleted") Integer deleted);


    BigDecimal selectPlateSize( @Param("orderId") Long orderId);


    List<Long> selectPlateIdListByBodyId(@Param("bodyId") Long bodyId, @Param("organId") Long organId);


    // 根据需要删除的小板id查找具体信息
    List<PlateGoodsIdVO> selectPlateGoodsListByList(@Param("plates") List<Long> goodsIdList, @Param("orderId") Long orderId, @Param("organId") Long organId);


    void deletedById(@Param("plateIds") List<Long> plateIds, @Param("organId") Long organId);


    @Select("select count(id) from order_plate where organ_id = #{organId} and deleted = false and order_id = #{orderId}")
    Integer selectPlateNum(@Param("orderId") Long orderId,@Param("organId") Long organId);


    /**
     * 查询商品id下未删除的板件
     *
     * @param orderId
     * @param goodsIds
     * @param organId
     * @return
     */
    default List<PlateDO> selectPlateDeletedStatus(Long orderId, Collection<Long> goodsIds, Long organId) {
        return selectList(new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId, organId)
                .eq(PlateDO::getDeleted, false)
                .in(PlateDO::getGoodsId, goodsIds)
                .eqIfPresent(PlateDO::getOrderId, orderId)
                .select(PlateDO::getGoodsId)
        );
    }



    //    房间id查小板的开料状态
    List<PlateDO> selectPlateTypeByRoomId(@Param("orderId") Long orderId, @Param("bodyIds") Collection<Long> bodyIds,
                                       @Param("organId") Long organId, @Param("deleted") Integer deleted);

    List<PlateDO> selectNoDeletedPlate(@Param("orderId") Long orderId, @Param("bodyIds") Collection<Long> bodyIds,@Param("organId") Long organId);

    /**
     * 查询订单条件下被删除的板件
     *
     * @param orderId
     * @param bodyIds
     * @param organId
     * @return
     */
    List<PlateDO> selectDeletedPlate(@Param("orderId") Long orderId, @Param("bodyIds") Collection<Long> bodyIds,@Param("organId") Long organId);

    //    根据订单id删除
    default int deleteByOrderId(Long orderId, Long organId) {
        return delete(new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId, organId)
                .eqIfPresent(PlateDO::getOrderId, orderId));
    }



    default List<PlateDO> selectPlateByPlateNo(List<Long> orderIdList,List<String> plateNo, Long organId) {
        return selectList(new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId,organId)
                .eq(PlateDO::getDeleted,false)
                .inIfPresent(PlateDO::getOrderId,orderIdList)
                .inIfPresent(PlateDO::getPlateNo, plateNo));

    }



    List<PlateDetailDO> selectPlateListByGoodsIds(@Param("orderId") Long orderId, @Param("organId")  Long organId);

    /**
     * 查询未排单板件
     *
     * @param orderIds
     * @param ids
     * @param organId
     * @return
     */
    List<PlateDetailDO> selectNoPlanPlate(@Param("orderIds") List<Long> orderIds,
                                          @Param("ids") List<Long> ids,
                                          @Param("roomIds") List<Long> roomIdList,
                                          @Param("bodyIds") List<Long> bodyIdList,
                                          @Param("organId") Long organId);

    /**
     * 查询未排单板件（带添加小板筛选）
     *
     * @return
     */
    List<PlateDetailDO> selectNoPlanPlateWithFilter(@Param("reqVO") NoPlanPlatePageReqVO reqVO, @Param("organId") Long organId);


    // 批量删除
    default int deleteBatch(Collection<?> orderId) {
        return delete(new LambdaQueryWrapperX<PlateDO>()
                .in(PlateDO::getOrderId, orderId));
    }


    List<PlateRespVO> selectPlanPlateListDataSource(@Param("filed") String filed, @Param("field2") String field2,@Param("goodsIdList")  List<Long> goodsIdList,@Param("orderIds") List<Long> orderIds,@Param("organId")  Long organId);


    default List<PlateDO> selectSelfincreasePlateIdList(Set<Long> orderIds, List<Long> planIds, Long organId) {
        return selectList(new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId,organId)
                .eq(PlateDO::getDeleted,false)
                .inIfPresent(PlateDO::getOrderId,orderIds)
                .inIfPresent(PlateDO::getPlanId, planIds)
                .eq(PlateDO::getType, OrderPlateTypeEnum.SELFINCREASINGBOARD.getType())
                .select(PlateDO::getId,PlateDO::getGoodsId));

    }

    void updatePlateOptimized(@Param("orderIdList") List<Long> orderIdList,@Param("ids") List<Long> ids,@Param("organId") Long organId);

    void updatePlateIsOptimized(@Param("orderIdList") List<Long> orderIdList,@Param("ids") List<Long> ids,@Param("plateIds") List<Long> plateIds,@Param("organId") Long organId);


    void updateNoPlateOptimized(@Param("orderIdList") List<Long> orderIdList,@Param("ids") List<Long> ids,@Param("plateIds") List<Long> plateIds,@Param("organId") Long organId);


    List<PrintOrderPackReqVO> selectPlanPackList(@Param("ids") List<Long> ids,@Param("organId")  Long organId);

    List<PrintOrderPackReqVO> selectOrderPackList(@Param("orderId") Long orderId,@Param("organId")  Long organId);

    void updatePlateOptimizedStatus(@Param("plateDOList")List<Long> plateDOList,@Param("organId") Long organId,@Param("orderId") Long orderId);



    default List<PlateDO> selectNoPlanPlate(Long orderId, List<Long> goodsIds, Long organId) {
        return selectList(new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId,organId)
                .eqIfPresent(PlateDO::getOrderId,orderId)
                .inIfPresent(PlateDO::getGoodsId,goodsIds)
                .eq(PlateDO::getIsOptimized,false));

    }



    default List<PlateDO> selectPlateIsOptimized(List<Long> orderId, Long organId) {
        return selectList(new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId,organId)
                .eq(PlateDO::getDeleted,false)
                .inIfPresent(PlateDO::getOrderId,orderId)
                .eq(PlateDO::getIsOptimized,true)
                .select(PlateDO::getId,PlateDO::getOrderId));

    }



    default List<PlateDO> selectPlateIds(List<Long> orderIds, List<Long> ids, Long organId) {
        return selectList(new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId,organId)
                .in(PlateDO::getOrderId,orderIds)
                .in(PlateDO::getGoodsId,ids)
                .eq(PlateDO::getDeleted,false)
                .select(PlateDO::getId));

    }




    default List<PlateDO> selectNoCutPlateByPlateId(List<Long> deleteOrderIds,Long organId) {
        return selectList(new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId,organId)
                .in(PlateDO::getOrderId,deleteOrderIds)
                .eq(PlateDO::getDeleted,false)
                .in(PlateDO::getIsCutted, Arrays.asList(OrderPlateCutStatusEnum.NOCUTTING.getStatus(),OrderPlateCutStatusEnum.OPENING.getStatus()))
                .select(PlateDO::getId,PlateDO::getOrderId));

    }



    default List<PlateDO> selectPlateIsCuttingStatus(List<Long> orderIds,Long organId) {
        return selectList(new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId,organId)
                .in(PlateDO::getOrderId,orderIds)
                .eq(PlateDO::getDeleted,false)
                .in(PlateDO::getIsCutted, Arrays.asList(OrderPlateCutStatusEnum.OPENED.getStatus(),OrderPlateCutStatusEnum.OPENING.getStatus()))
                .select(PlateDO::getId,PlateDO::getOrderId));

    }


    List<PlateGoodsRespVO> selectOrderPlateList(@Param("orderId") Long orderId,
                                                @Param("organId") Long organId,
                                                @Param("deleted") Integer deleted,
                                                @Param("roomId")Long roomId,
                                                @Param("bodyId")Long bodyId,
                                                @Param("plateId")Long goodsId); // 明细

    List<PlateGoodsRespVO> selectOrderPlateListSummary(@Param("orderId") Long orderId,
                                                       @Param("organId") Long organId,
                                                       @Param("deleted") Integer deleted,
                                                       @Param("roomId")Long roomId,
                                                       @Param("bodyId")Long bodyId,
                                                       @Param("plateId")Long goodsId); // 汇总

    List<PlateDetails> selectListByOrderId(@Param("orderId") Long orderId, @Param("organId") Long organId);


    default List<PlateDO> selectplateByPlateNoList(String plateNo, Long orderId, Long organId) {
        return selectList(new LambdaQueryWrapperX<PlateDO>()
                .eq(PlateDO::getOrganId, organId)
                .eq(PlateDO::getDeleted,false)
                .eq(PlateDO::getOrderId, orderId)
                .likeIfPresent(PlateDO::getPlateNo, plateNo)
                .select(PlateDO::getId));
    }

    List<PlateDetailsRespVO> selectOrderNoPackPlateList(@Param("orderId") Long orderId, @Param("organId") Long organId);

    /**
     * 查询订单列表下未打包的板件
     *
     * @param orderIds
     * @return
     */
    List<PlateDetailsRespVO> selectOrdersPackPlateList(@Param("orderIds") List<Long> orderIds);

    /**
     * 查询包裹板件列表
     *
     * @param orderIds
     * @param packageNo
     * @return
     */
    List<PackageDetailsRespVO> selectPackedPlateList(@Param("orderIds") Set<Long> orderIds, @Param("packageNo") String packageNo);

    /**
     * 查询订单列表下分堆列表
     *
     * @param orderIds
     * @return
     */
    List<PlateDetailsRespVO> selectOrdersHeapSplitPlateList(@Param("orderIds") List<Long> orderIds);

    List<LabelOrderPlateData> selectLabelOrderPlateDataByOrderId(@Param("orderId") Long orderId,@Param("organId") Long organId);

    /**
     * 更新订单部件板件
     *
     * @param orderId
     * @param componentIds
     * @param deleted      true:删除，false恢复
     * @return
     */
    int updateOrderComponentPlate(@Param("orderId") Long orderId, @Param("componentIds") List<Long> componentIds, @Param("deleted") boolean deleted);

    /**
     * 查询部件下板件用到的order_goods id
     *
     * @param componentIds
     * @param deleted true：查order_item_temp、false：查order_item
     * @return
     */
    List<Long> selectOrderComponentGoodsIds(@Param("orderId") Long orderId, @Param("componentIds") List<Long> componentIds, @Param("deleted") boolean deleted);

    /**
     * 查询部件下板件用到的柜体id
     *
     * @param orderId
     * @param componentIds
     * @return
     */
    List<Long> selectOrderComponentBodyIds(@Param("orderId") Long orderId, @Param("componentIds") List<Long> componentIds, @Param("deleted") boolean deleted);

    /**
     * 根据板件id列表查询板件信息
     *
     * @param orderIds
     * @param plateIds
     * @param deleted
     * @return
     */
    List<OrdersViewPlatesPageDO> selectPlateGoodsByIds(@Param("orderIds") List<Long> orderIds, @Param("plateIds") List<Long> plateIds, @Param("deleted") boolean deleted);

    /**
     * 更新计划板件优化状态
     *
     * @param planId
     * @param orderIds
     * @return
     */
    int updatePlanPlateOptimizeStatus(@Param("planId") Long planId, @Param("orderIds") List<Long> orderIds, @Param("plateNos") List<String> plateNoList);

    /**
     * 更新计划板件开料状态
     *
     * @param planId
     * @param orderIds
     * @return
     */
    int updatePlanPlateCutStatus(@Param("planId") Long planId, @Param("orderIds") List<Long> orderIds, @Param("plateNos") List<String> plateNoList);

    /**
     * 更新计划板件开料中状态
     *
     * @param planId
     * @param orderIds
     * @return
     */
    int updatePlanPlateCuttingStatus(@Param("planId") Long planId, @Param("orderIds") List<Long> orderIds, @Param("plateNos") List<String> plateNoList);

    /**
     * 根据板件id列表查询板件信息
     *
     * @param orderIds
     * @param orderIds
     * @return
     */
    int resetPlanPlateOptimizeStatus(@Param("planId") Long planId, @Param("orderIds") List<Long> orderIds);

    /**
     * 查询排单下已全部开料的订单id列表
     *
     * @param planId
     * @return
     */
    List<Long> selectPlanAllCuttedOrderIdList(@Param("planId") Long planId, @Param("orderIds") List<Long> orderIds);

    /**
     * 查询排单板件信息
     *
     * @param planIds
     * @return
     */
    IPage<OrdersViewPlatesPageDO> selectPlanPlateInfoPage(@Param("page") IPage<OrdersViewPlatesPageDO> page, @Param("planIds") List<Long> planIds, @Param("orderIds") Set<Long> orderIds);

    /**
     * 物理删除订单材质
     *
     * @return
     */
    int physicalDeleteByOrderIds(@Param("ids") List<Long> ids);

    /**
     * 查询订单下板件的排单id列表
     *
     * @param orderIds
     * @param customer
     * @return
     */
    List<Long> selectPlanIdsByOrderCondition(@Param("orderIds") List<Long> orderIds, @Param("customer") String customer, @Param("organId") Long organId);
}