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

import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import com.yhy.module.core.dal.dataobject.resource.ResourceItemDO;
import java.math.BigDecimal;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

@Mapper
public interface ResourceItemMapper extends BaseMapperX<ResourceItemDO> {

    /**
     * 根据工料机机类树节点ID查询工料机列表
     * 
     * 用于定额基价工料机的范围过滤
     * 通过 catalog_item_id 关联 yhy_catalog_item 表，再过滤 category_tree_id
     */
    @Select("SELECT ri.* FROM yhy_resource_item ri " +
            "INNER JOIN yhy_catalog_item rci ON ri.catalog_item_id = rci.id " +
            "WHERE rci.category_tree_id = #{categoryTreeId} " +
            "AND ri.deleted = 0 " +
            "AND rci.deleted = 0 " +
            "ORDER BY ri.id")
    List<ResourceItemDO> selectByCategoryTreeId(@Param("categoryTreeId") Long categoryTreeId);

    /**
     * 根据工料机机类树节点ID和查询条件查询工料机列表（支持模糊查询）
     * 
     * @param categoryTreeId 工料机机类树节点ID
     * @param code 编码（模糊查询）
     * @param name 名称（模糊查询）
     * @param spec 型号规格（模糊查询）
     * @return 工料机列表
     */
    @Select("<script>" +
            "SELECT ri.* FROM yhy_resource_item ri " +
            "INNER JOIN yhy_catalog_item rci ON ri.catalog_item_id = rci.id " +
            "WHERE rci.category_tree_id = #{categoryTreeId} " +
            "AND ri.deleted = 0 " +
            "AND rci.deleted = 0 " +
            "<if test='code != null and code != \"\"'>" +
            "AND ri.code LIKE CONCAT('%', #{code}, '%') " +
            "</if>" +
            "<if test='name != null and name != \"\"'>" +
            "AND ri.name LIKE CONCAT('%', #{name}, '%') " +
            "</if>" +
            "<if test='spec != null and spec != \"\"'>" +
            "AND ri.spec LIKE CONCAT('%', #{spec}, '%') " +
            "</if>" +
            "ORDER BY ri.id" +
            "</script>")
    List<ResourceItemDO> selectByCategoryTreeIdWithFilter(
            @Param("categoryTreeId") Long categoryTreeId,
            @Param("code") String code,
            @Param("name") String name,
            @Param("spec") String spec);

    /**
     * 批量查询工料机项（根据ID列表）
     *
     * @param ids ID列表
     * @return 工料机项列表
     */
    default List<ResourceItemDO> selectBatchIds(List<Long> ids) {
        return selectList("id", ids);
    }

    /**
     * 更新工料机的4个价格字段
     *
     * @param id 工料机ID
     * @param taxExclBasePrice 除税基价
     * @param taxInclBasePrice 含税基价
     * @param taxExclCompilePrice 除税编制价
     * @param taxInclCompilePrice 含税编制价
     */
    @Update("UPDATE yhy_resource_item SET " +
            "tax_excl_base_price = #{taxExclBasePrice}, " +
            "tax_incl_base_price = #{taxInclBasePrice}, " +
            "tax_excl_compile_price = #{taxExclCompilePrice}, " +
            "tax_incl_compile_price = #{taxInclCompilePrice}, " +
            "update_time = now() " +
            "WHERE id = #{id} AND deleted = 0")
    void updatePrices(@Param("id") Long id,
                      @Param("taxExclBasePrice") BigDecimal taxExclBasePrice,
                      @Param("taxInclBasePrice") BigDecimal taxInclBasePrice,
                      @Param("taxExclCompilePrice") BigDecimal taxExclCompilePrice,
                      @Param("taxInclCompilePrice") BigDecimal taxInclCompilePrice);

    /**
     * 清空工料机的税率字段（用于复合工料机）
     *
     * @param id 工料机ID
     */
    @Update("UPDATE yhy_resource_item SET " +
            "tax_rate = NULL, " +
            "update_time = now() " +
            "WHERE id = #{id} AND deleted = 0")
    void clearTaxRate(@Param("id") Long id);

    /**
     * 清空工料机的四个价格字段（用于复合工料机）
     *
     * @param id 工料机ID
     */
    @Update("UPDATE yhy_resource_item SET " +
            "tax_excl_base_price = NULL, " +
            "tax_incl_base_price = NULL, " +
            "tax_excl_compile_price = NULL, " +
            "tax_incl_compile_price = NULL, " +
            "update_time = now() " +
            "WHERE id = #{id} AND deleted = 0")
    void clearPriceFields(@Param("id") Long id);

    /**
     * 查询复合工料机的所有子工料机数据（用于计算合价总和）
     * 注意：单位为 % 的子工料机需要在 Service 层根据 calc_base 计算
     * 
     * @param mergedId 复合工料机ID
     * @return 子工料机列表（包含价格、定额消耗量、单位、计算基数、类别ID等信息）
     */
    @Select("SELECT " +
            "  rm.id, rm.source_id, rm.quota_consumption, " +
            "  ri.unit, ri.calc_base, ri.category_id, " +
            "  ri.tax_excl_base_price, ri.tax_incl_base_price, " +
            "  ri.tax_excl_compile_price, ri.tax_incl_compile_price " +
            "FROM yhy_resource_merged rm " +
            "LEFT JOIN yhy_resource_item ri ON rm.source_id = ri.id AND ri.deleted = 0 " +
            "WHERE rm.merged_id = #{mergedId} AND rm.deleted = 0")
    List<java.util.Map<String, Object>> selectMergedChildrenForSum(@Param("mergedId") Long mergedId);
    
    /**
     * 更新工料机的 is_merged 标记
     *
     * @param id 工料机ID
     * @param isMerged 是否为复合工料机（0=否，1=是）
     */
    @Update("UPDATE yhy_resource_item SET " +
            "is_merged = #{isMerged}, " +
            "update_time = now() " +
            "WHERE id = #{id} AND deleted = 0")
    void updateIsMerged(@Param("id") Long id, @Param("isMerged") Integer isMerged);

    /**
     * 根据编码查询工料机
     *
     * @param code 工料机编码
     * @return 工料机项，如果不存在返回null
     */
    @Select("SELECT * FROM yhy_resource_item WHERE code = #{code} AND deleted = 0 LIMIT 1")
    ResourceItemDO selectByCode(@Param("code") String code);

    /**
     * 根据工料机机类树节点ID和编码精确查询工料机
     * 
     * @param categoryTreeId 工料机机类树节点ID
     * @param code 工料机编码
     * @return 工料机项，如果不存在返回null
     */
    @Select("SELECT ri.* FROM yhy_resource_item ri " +
            "INNER JOIN yhy_catalog_item rci ON ri.catalog_item_id = rci.id " +
            "WHERE rci.category_tree_id = #{categoryTreeId} " +
            "AND ri.code = #{code} " +
            "AND ri.deleted = 0 " +
            "AND rci.deleted = 0 " +
            "LIMIT 1")
    ResourceItemDO selectByCategoryTreeIdAndCode(@Param("categoryTreeId") Long categoryTreeId, @Param("code") String code);

    /**
     * 根据名称、型号规格、单位查询工料机（全局唯一约束）
     *
     * @param name 名称
     * @param spec 型号规格
     * @param unit 单位
     * @return 工料机项，如果不存在返回null
     */
    @Select("<script>" +
            "SELECT * FROM yhy_resource_item WHERE deleted = 0 " +
            "AND name = #{name} " +
            "<if test='spec != null'>AND spec = #{spec} </if>" +
            "<if test='spec == null'>AND spec IS NULL </if>" +
            "AND unit = #{unit} " +
            "LIMIT 1" +
            "</script>")
    ResourceItemDO selectByNameSpecUnit(@Param("name") String name, @Param("spec") String spec, @Param("unit") String unit);

    /**
     * 查询同目录节点下的最大排序值
     *
     * @param catalogItemId 目录节点ID
     * @return 最大排序值，如果没有数据返回0
     */
    @Select("SELECT COALESCE(MAX(sort_order), 0) FROM yhy_resource_item " +
            "WHERE catalog_item_id = #{catalogItemId} AND deleted = 0")
    Integer selectMaxSortOrder(@Param("catalogItemId") Long catalogItemId);

    /**
     * 将指定目录节点下，排序值 >= sortOrder 的行的排序值都加1（通过XML实现）
     *
     * @param catalogItemId 目录节点ID
     * @param sortOrder 起始排序值
     */
    void incrementSortOrderFrom(@Param("catalogItemId") Long catalogItemId,
                                @Param("sortOrder") Integer sortOrder);
}
