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

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerPlanPageReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerPlanPageRespVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerPlanPlateRespVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerPlanSortReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerPlanSortRespVO;
import com.cf.imes.module.executor.dal.dataobject.veneer.OrderPlateVeneerDO;
import com.cf.imes.module.executor.dal.dataobject.veneer.OrderVeneerPlanDO;
import com.cf.imes.module.executor.dal.dataobject.veneer.VeneerPlannedPlateCountDO;
import com.cf.imes.module.executor.dal.dataobject.veneer.VeneerPlanStatisticsDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 贴皮排单 Mapper。
 */
@Mapper
public interface VeneerPlanMapper extends BaseMapperX<OrderVeneerPlanDO> {

    /**
     * 分页查询贴皮排单及其关联的贴皮库信息。
     *
     * @param page 分页参数
     * @param req 筛选条件
     * @return 贴皮排单分页数据
     */
    IPage<VeneerPlanPageRespVO> selectPlanPage(
            @Param("page") IPage<VeneerPlanPageRespVO> page,
            @Param("req") VeneerPlanPageReqVO req);

    /**
     * 查询指定排单下的贴皮明细。
     *
     * @param planId 贴皮排单ID
     * @return 排单贴皮明细列表
     */
    List<VeneerPlanPlateRespVO> selectPlanPlateList(@Param("planId") Long planId);

    /**
     * 查询尚未完成开料的贴皮排单优先级列表。
     *
     * @param openedStatus 已开料状态
     * @return 按优先级升序排列的贴皮排单
     */
    List<VeneerPlanSortRespVO> selectPlanSortList(
            @Param("openedStatus") Integer openedStatus);

    /**
     * 批量更新尚未完成开料的贴皮排单优先级。
     *
     * @param sortList 排单ID及排序值列表
     * @param openedStatus 已开料状态
     * @return 更新行数
     */
    int batchUpdatePlanSort(@Param("sortList") List<VeneerPlanSortReqVO> sortList,
                            @Param("openedStatus") Integer openedStatus);

    /**
     * 查询属于指定排单且仍为已排单状态的贴皮记录。
     *
     * @param ids 板件贴皮记录ID列表
     * @param planId 贴皮排单ID
     * @return 符合条件的贴皮记录
     */
    List<OrderPlateVeneerDO> selectPlannedVeneerList(
            @Param("ids") List<Long> ids,
            @Param("planId") Long planId);

    /**
     * 将指定贴皮记录从排单中恢复为待排单状态。
     *
     * @param ids 板件贴皮记录ID列表
     * @param planId 贴皮排单ID
     * @return 更新行数
     */
    int resetPlanVeneer(@Param("ids") List<Long> ids,
                        @Param("planId") Long planId);

    /**
     * 根据排单当前关联贴皮重新统计数量和面积。
     *
     * @param planId 贴皮排单ID
     * @return 排单贴皮数量及面积
     */
    VeneerPlanStatisticsDO selectPlanStatistics(@Param("planId") Long planId);

    /**
     * 按版本物理删除已无关联贴皮且未进入开料阶段的排单。
     *
     * @param planId 贴皮排单ID
     * @param openingStatus 开料中状态
     * @param openedStatus 已开料状态
     * @param version 当前版本号
     * @return 删除行数
     */
    int physicalDeleteEmptyPlan(@Param("planId") Long planId,
                                @Param("openingStatus") Integer openingStatus,
                                @Param("openedStatus") Integer openedStatus,
                                @Param("version") Integer version);

    /**
     * 查询仍处于待排单状态的贴皮记录。
     *
     * @param ids 板件贴皮记录ID列表
     * @return 可创建排单的贴皮记录
     */
    List<OrderPlateVeneerDO> selectPendingVeneerList(@Param("ids") List<Long> ids);

    /**
     * 将一批贴皮记录关联到指定贴皮排单。
     *
     * @param ids 板件贴皮记录ID列表
     * @param planId 贴皮排单ID
     * @return 更新行数
     */
    int updateVeneerPlanned(@Param("ids") List<Long> ids,
                            @Param("planId") Long planId);

    /**
     * 按订单重新统计所有有效贴皮面均已排单的原始板件数量。
     *
     * @param orderIds 订单ID列表
     * @return 订单及其所有贴皮面均已排单的板件数量
     */
    List<VeneerPlannedPlateCountDO> selectOrderPlannedVeneerPlateCount(
            @Param("orderIds") List<Long> orderIds);

    /**
     * 按订单材质重新统计所有有效贴皮面均已排单的原始板件数量。
     *
     * @param orderGoodsIds {@code order_goods} 主键列表
     * @return 订单材质及其所有贴皮面均已排单的板件数量
     */
    List<VeneerPlannedPlateCountDO> selectGoodsPlannedVeneerPlateCount(
            @Param("orderGoodsIds") List<Long> orderGoodsIds);

    /**
     * 查询待删除排单影响的订单和订单材质范围。
     *
     * @param planIds 贴皮排单ID列表
     * @return 受影响的订单及订单材质
     */
    List<OrderPlateVeneerDO> selectPlanAffectedScope(@Param("planIds") List<Long> planIds);

    /**
     * 将指定排单内的板件贴皮恢复为待排单状态。
     *
     * @param planIds 贴皮排单ID列表
     * @return 更新行数
     */
    int resetVeneerPlan(@Param("planIds") List<Long> planIds);

    /**
     * 物理删除指定状态的贴皮排单。
     *
     * @param planIds 贴皮排单ID列表
     * @param openingStatus 开料中状态
     * @param openedStatus 已开料状态
     * @return 删除行数
     */
    int physicalDeletePlan(@Param("planIds") List<Long> planIds,
                           @Param("openingStatus") Integer openingStatus,
                           @Param("openedStatus") Integer openedStatus);
}
