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

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yhy.module.core.controller.admin.workbench.vo.HistoryBoqListReqVO;
import com.yhy.module.core.dal.dataobject.workbench.WbBoqDivisionDO;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;

/**
 * 工作台分部分项树 Mapper
 *
 * @author yhy
 */
@Mapper
public interface WbBoqDivisionMapper extends BaseMapperX<WbBoqDivisionDO> {

    /**
     * 根据单位工程节点ID查询所有分部分项节点
     */
    default List<WbBoqDivisionDO> selectListByCompileTreeId(Long compileTreeId) {
        return selectList(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getCompileTreeId, compileTreeId)
                .orderByAsc(WbBoqDivisionDO::getSortOrder));
    }

    /**
     * 根据父节点ID查询子节点列表
     */
    default List<WbBoqDivisionDO> selectListByParentId(Long parentId) {
        return selectList(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getParentId, parentId)
                .orderByAsc(WbBoqDivisionDO::getSortOrder));
    }

    /**
     * 根据单位工程节点ID查询分部节点（根节点）
     */
    default List<WbBoqDivisionDO> selectDivisionsByCompileTreeId(Long compileTreeId) {
        return selectList(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getCompileTreeId, compileTreeId)
                .eq(WbBoqDivisionDO::getNodeType, WbBoqDivisionDO.NODE_TYPE_DIVISION)
                .isNull(WbBoqDivisionDO::getParentId)
                .orderByAsc(WbBoqDivisionDO::getSortOrder));
    }

    /**
     * 获取同级最大排序号
     */
    default Integer selectMaxSortOrderByParentId(Long compileTreeId, Long parentId) {
        LambdaQueryWrapperX<WbBoqDivisionDO> wrapper = new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getCompileTreeId, compileTreeId)
                .orderByDesc(WbBoqDivisionDO::getSortOrder)
                .last("LIMIT 1");
        if (parentId != null) {
            wrapper.eq(WbBoqDivisionDO::getParentId, parentId);
        } else {
            wrapper.isNull(WbBoqDivisionDO::getParentId);
        }
        WbBoqDivisionDO maxSortNode = selectOne(wrapper);
        return maxSortNode != null ? maxSortNode.getSortOrder() : 0;
    }

    /**
     * 根据节点类型查询
     */
    default List<WbBoqDivisionDO> selectListByNodeType(Long compileTreeId, String nodeType) {
        return selectList(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getCompileTreeId, compileTreeId)
                .eq(WbBoqDivisionDO::getNodeType, nodeType)
                .orderByAsc(WbBoqDivisionDO::getSortOrder));
    }

    /**
     * 查询子节点数量
     */
    default Long selectCountByParentId(Long parentId) {
        return selectCount(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getParentId, parentId));
    }

    /**
     * 根据引用定额ID查询
     */
    default List<WbBoqDivisionDO> selectListBySourceQuotaItemId(Long sourceQuotaItemId) {
        return selectList(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getSourceQuotaItemId, sourceQuotaItemId));
    }

    /**
     * 查询单位工程下所有定额节点（有sourceQuotaItemId的）
     */
    default List<WbBoqDivisionDO> selectQuotaNodesByCompileTreeId(Long compileTreeId) {
        return selectList(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getCompileTreeId, compileTreeId)
                .eq(WbBoqDivisionDO::getNodeType, WbBoqDivisionDO.NODE_TYPE_QUOTA)
                .isNotNull(WbBoqDivisionDO::getSourceQuotaItemId));
    }

    /**
     * 查询租户所有清单节点（跨项目）
     */
    default List<WbBoqDivisionDO> selectAllBoqNodes() {
        return selectList(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getNodeType, WbBoqDivisionDO.NODE_TYPE_BOQ)
                .orderByDesc(WbBoqDivisionDO::getCreateTime));
    }

    /**
     * 查询清单节点及其子节点（定额）
     */
    default List<WbBoqDivisionDO> selectBoqWithChildren(Long boqId) {
        // 先获取清单节点
        WbBoqDivisionDO boq = selectById(boqId);
        if (boq == null) {
            return java.util.Collections.emptyList();
        }
        // 获取清单及其子节点（定额）
        List<WbBoqDivisionDO> result = new java.util.ArrayList<>();
        result.add(boq);
        result.addAll(selectListByParentId(boqId));
        return result;
    }

    /**
     * 查询历史清单/分部列表（支持查询条件）
     */
    default List<WbBoqDivisionDO> selectHistoryList(HistoryBoqListReqVO reqVO) {
        LambdaQueryWrapperX<WbBoqDivisionDO> wrapper = new LambdaQueryWrapperX<>();
        
        // 根据类别筛选节点类型
        if (StrUtil.isNotBlank(reqVO.getCategory())) {
            if ("division".equals(reqVO.getCategory())) {
                wrapper.eq(WbBoqDivisionDO::getNodeType, WbBoqDivisionDO.NODE_TYPE_DIVISION);
            } else if ("boq".equals(reqVO.getCategory())) {
                wrapper.eq(WbBoqDivisionDO::getNodeType, WbBoqDivisionDO.NODE_TYPE_BOQ);
            }
        } else {
            // 默认查询清单和分部
            wrapper.in(WbBoqDivisionDO::getNodeType, 
                    WbBoqDivisionDO.NODE_TYPE_BOQ, 
                    WbBoqDivisionDO.NODE_TYPE_DIVISION);
        }
        
        // 注意：清单章节筛选已移至 Service 层通过 sourceBoqItemTreeId 关联 BoqItemTree.boqCatalogItemId 实现
        
        // 名称模糊查询
        if (StrUtil.isNotBlank(reqVO.getName())) {
            wrapper.like(WbBoqDivisionDO::getName, reqVO.getName());
        }
        
        // 项目特征模糊查询
        if (StrUtil.isNotBlank(reqVO.getFeature())) {
            wrapper.like(WbBoqDivisionDO::getFeature, reqVO.getFeature());
        }
        
        // 时间范围筛选
        if (reqVO.getStartTime() != null) {
            LocalDateTime startDateTime = LocalDateTime.ofInstant(
                    Instant.ofEpochMilli(reqVO.getStartTime()), ZoneId.systemDefault());
            wrapper.ge(WbBoqDivisionDO::getCreateTime, startDateTime);
        }
        if (reqVO.getEndTime() != null) {
            LocalDateTime endDateTime = LocalDateTime.ofInstant(
                    Instant.ofEpochMilli(reqVO.getEndTime()), ZoneId.systemDefault());
            wrapper.le(WbBoqDivisionDO::getCreateTime, endDateTime);
        }
        
        // 按创建时间倒序
        wrapper.orderByDesc(WbBoqDivisionDO::getCreateTime);
        
        return selectList(wrapper);
    }

    /**
     * 统计同一单位工程下相同编码的清单数量（用于唯一性校验）
     * @param compileTreeId 单位工程ID
     * @param code 清单编码
     * @param excludeId 排除的节点ID（更新时排除自身）
     */
    default Long countBoqByCodeAndCompileTreeId(Long compileTreeId, String code, Long excludeId) {
        LambdaQueryWrapperX<WbBoqDivisionDO> wrapper = new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getCompileTreeId, compileTreeId)
                .eq(WbBoqDivisionDO::getNodeType, WbBoqDivisionDO.NODE_TYPE_BOQ)
                .eq(WbBoqDivisionDO::getCode, code);
        if (excludeId != null) {
            wrapper.ne(WbBoqDivisionDO::getId, excludeId);
        }
        return selectCount(wrapper);
    }

    /**
     * 查询单位工程下指定费率模式的统一取费节点
     * 统一取费节点的 rateModeId 存储在 attributes JSONB 字段中
     */
    default List<WbBoqDivisionDO> selectUnifiedFeeNodesByRateModeId(Long compileTreeId, Long rateModeId) {
        return selectList(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getCompileTreeId, compileTreeId)
                .eq(WbBoqDivisionDO::getNodeType, "unified_fee")
                .apply("attributes->>'rateModeId' = {0}", String.valueOf(rateModeId)));
    }

    /**
     * 删除单位工程下指定费率模式的统一取费节点
     */
    default int deleteUnifiedFeeNodesByRateModeId(Long compileTreeId, Long rateModeId) {
        return delete(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getCompileTreeId, compileTreeId)
                .eq(WbBoqDivisionDO::getNodeType, "unified_fee")
                .apply("attributes->>'rateModeId' = {0}", String.valueOf(rateModeId)));
    }

    /**
     * 删除单位工程下不属于指定费率模式的统一取费节点（费率切换时清空其他费率模式的节点）
     */
    default int deleteUnifiedFeeNodesExcludeRateModeId(Long compileTreeId, Long rateModeId) {
        return delete(new LambdaQueryWrapperX<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getCompileTreeId, compileTreeId)
                .eq(WbBoqDivisionDO::getNodeType, "unified_fee")
                .apply("attributes->>'rateModeId' <> {0}", String.valueOf(rateModeId)));
    }

    /**
     * 清理指定同步库关联的同步状态（sync_library_id 和 is_sync_source）
     * 用于同步库删除时防止脏数据
     */
    default int clearSyncStatus(Long syncLibraryId) {
        return update(null, new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<WbBoqDivisionDO>()
                .eq(WbBoqDivisionDO::getSyncLibraryId, syncLibraryId)
                .set(WbBoqDivisionDO::getSyncLibraryId, null)
                .set(WbBoqDivisionDO::getIsSyncSource, false));
    }
}
