package com.yhy.module.core.dal.mysql.workbench;

import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yhy.module.core.dal.dataobject.workbench.WbBoqResourceDO;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

/**
 * 工作台工料机消耗 Mapper
 *
 * @author yhy
 */
@Mapper
public interface WbBoqResourceMapper extends BaseMapperX<WbBoqResourceDO> {

    /**
     * 根据定额节点ID查询工料机列表
     */
    default List<WbBoqResourceDO> selectListByDivisionId(Long divisionId) {
        return selectList(new LambdaQueryWrapperX<WbBoqResourceDO>()
                .eq(WbBoqResourceDO::getDivisionId, divisionId)
                .orderByAsc(WbBoqResourceDO::getSortOrder));
    }

    /**
     * 根据定额节点ID列表批量查询工料机
     */
    default List<WbBoqResourceDO> selectListByDivisionIds(List<Long> divisionIds) {
        return selectList(new LambdaQueryWrapperX<WbBoqResourceDO>()
                .in(WbBoqResourceDO::getDivisionId, divisionIds)
                .orderByAsc(WbBoqResourceDO::getSortOrder));
    }

    /**
     * 根据资源类型查询
     */
    default List<WbBoqResourceDO> selectListByResourceType(Long divisionId, String resourceType) {
        return selectList(new LambdaQueryWrapperX<WbBoqResourceDO>()
                .eq(WbBoqResourceDO::getDivisionId, divisionId)
                .eq(WbBoqResourceDO::getResourceType, resourceType)
                .orderByAsc(WbBoqResourceDO::getSortOrder));
    }

    /**
     * 获取同级最大排序号
     */
    default Integer selectMaxSortOrderByDivisionId(Long divisionId) {
        WbBoqResourceDO maxSortNode = selectOne(new LambdaQueryWrapperX<WbBoqResourceDO>()
                .eq(WbBoqResourceDO::getDivisionId, divisionId)
                .orderByDesc(WbBoqResourceDO::getSortOrder)
                .last("LIMIT 1"));
        return maxSortNode != null ? maxSortNode.getSortOrder() : 0;
    }

    /**
     * 根据定额节点ID删除所有工料机
     */
    default int deleteByDivisionId(Long divisionId) {
        return delete(new LambdaQueryWrapperX<WbBoqResourceDO>()
                .eq(WbBoqResourceDO::getDivisionId, divisionId));
    }

    /**
     * 根据引用定额工料机组成ID查询（用于统计引用次数）
     */
    default List<WbBoqResourceDO> selectListBySourceQuotaResourceId(Long sourceQuotaResourceId) {
        return selectList(new LambdaQueryWrapperX<WbBoqResourceDO>()
                .eq(WbBoqResourceDO::getSourceQuotaResourceId, sourceQuotaResourceId));
    }

    /**
     * 统计引用定额工料机组成的数量
     */
    default Long selectCountBySourceQuotaResourceId(Long sourceQuotaResourceId) {
        return selectCount(new LambdaQueryWrapperX<WbBoqResourceDO>()
                .eq(WbBoqResourceDO::getSourceQuotaResourceId, sourceQuotaResourceId));
    }

    /**
     * 根据编制模式树ID（单位工程）和编码模糊查询工料机
     * 用于新增工料机弹窗的"本项目"范围查询
     */
    default List<WbBoqResourceDO> selectByCompileTreeIdAndCodeLike(Long compileTreeId, String code) {
        return selectList(new LambdaQueryWrapperX<WbBoqResourceDO>()
                .inSql(WbBoqResourceDO::getDivisionId,
                        "SELECT id FROM yhy_wb_boq_division WHERE compile_tree_id = " + compileTreeId
                                + " AND node_type = 'quota' AND deleted = 0")
                .like(WbBoqResourceDO::getCode, code)
                .isNull(WbBoqResourceDO::getParentId)
                .orderByAsc(WbBoqResourceDO::getCode));
    }

    /**
     * 将指定定额节点下排序号大于指定值的工料机排序号+1
     * 用于在某行下方插入空白行
     */
    default void incrementSortOrderAfter(Long divisionId, Integer afterSortOrder) {
        update(null, new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<WbBoqResourceDO>()
                .eq(WbBoqResourceDO::getDivisionId, divisionId)
                .gt(WbBoqResourceDO::getSortOrder, afterSortOrder)
                .setSql("sort_order = sort_order + 1"));
    }

    /**
     * 查询同项目下"编码+名称+型号规格+单位"一致的工料机（排除自身）
     * 用于编制价/价格来源的项目级批量同步
     *
     * @param projectId 项目ID
     * @param code 编码
     * @param name 名称
     * @param spec 型号规格
     * @param unit 单位
     * @param excludeId 排除的工料机ID
     * @return 匹配的工料机列表
     */
    @Select("<script>"
            + "SELECT r.* FROM yhy_wb_boq_resource r "
            + "INNER JOIN yhy_wb_boq_division d ON r.division_id = d.id AND d.deleted = 0 "
            + "INNER JOIN yhy_wb_compile_tree c ON d.compile_tree_id = c.id AND c.deleted = 0 "
            + "WHERE c.project_id = #{projectId} "
            + "AND r.deleted = 0 "
            + "AND r.code = #{code} "
            + "AND r.name = #{name} "
            + "<if test='spec != null'>AND r.spec = #{spec} </if>"
            + "<if test='spec == null'>AND (r.spec IS NULL OR r.spec = '') </if>"
            + "AND r.unit = #{unit} "
            + "AND r.id != #{excludeId} "
            + "AND r.parent_id IS NULL "
            + "ORDER BY r.id"
            + "</script>")
    List<WbBoqResourceDO> selectSameResourceInProject(
            @Param("projectId") Long projectId,
            @Param("code") String code,
            @Param("name") String name,
            @Param("spec") String spec,
            @Param("unit") String unit,
            @Param("excludeId") Long excludeId);
}
