"""
文本块合并模块
用于合并小于最小尺寸的文本块
"""

try:
    from .text_utils import TextUtils
except ImportError:
    from text_utils import TextUtils


class ChunkMerger:
    """文本块合并器"""
    
    def __init__(self):
        self.text_utils = TextUtils()
    
    def merge_small_chunks(self, chunks, max_chunk_size, min_chunk_size, target_level=1):
        """
        合并小于min_chunk_size的块（复用测试目录的逻辑）
        
        参数:
            chunks: 块列表
            max_chunk_size: 最大分块字符数
            min_chunk_size: 最小分块字符数
            target_level: 目标层级（已废弃，保留以兼容）
            
        返回:
            list: 合并后的块列表
        """
        if not chunks:
            return []
        
        # 先按最低层级标题编号分组处理（在同一标题内合并）
        current_title_number = None
        title_groups = []
        current_group = []
        
        for chunk in chunks:
            title_number = chunk.get('_title_number', '')
            
            if title_number != current_title_number:
                # 保存上一组
                if current_group:
                    title_groups.append({
                        'title_number': current_title_number,
                        'chunks': current_group
                    })
                # 开始新组
                current_title_number = title_number
                current_group = [chunk]
            else:
                current_group.append(chunk)
        
        # 保存最后一组
        if current_group:
            title_groups.append({
                'title_number': current_title_number,
                'chunks': current_group
            })
        
        # 在每个组内合并小块
        merged_groups = []
        for group in title_groups:
            merged_chunks = self.merge_within_title(group['chunks'], max_chunk_size, min_chunk_size)
            merged_groups.append({
                'title_number': group['title_number'],
                'chunks': merged_chunks
            })
        
        # 处理跨标题合并：如果上一组的最后一个块与当前组的第一个块都是小块，可以合并
        # 但是不能跨越一级标题（章）进行合并
        final_merged = []
        for i, group in enumerate(merged_groups):
            if i == 0:
                final_merged.extend(group['chunks'])
            else:
                # 检查是否可以与上一组的最后一个块合并
                prev_group = merged_groups[i - 1]
                if prev_group['chunks'] and group['chunks']:
                    prev_last = prev_group['chunks'][-1]
                    curr_first = group['chunks'][0]
                    
                    prev_content = prev_last['review_chunk_content']
                    curr_content = curr_first['review_chunk_content']
                    
                    # 检查是否有公共前缀（至少一级标题相同）
                    has_common_prefix = self._has_common_prefix(
                        prev_last.get('section_label', ''),
                        curr_first.get('section_label', '')
                    )
                    
                    # 如果两个块都是小块且不是分割块，且有公共前缀（不跨章），可以合并
                    if (has_common_prefix and  # 关键检查：必须有至少一个公共前缀层级
                        not prev_last.get('is_split', False) and 
                        not curr_first.get('is_split', False) and
                        len(prev_content) < min_chunk_size and
                        len(curr_content) < min_chunk_size and
                        len(prev_content) + len(curr_content) <= max_chunk_size):
                        
                        # 合并
                        merged_content = prev_content + '\n\n' + curr_content
                        merged_chunk = prev_last.copy()
                        merged_chunk['review_chunk_content'] = merged_content
                        merged_chunk['section_label'] = self.merge_section_labels(
                            prev_last['section_label'],
                            curr_first['section_label']
                        )
                        # 合并标题编号（按照测试目录的逻辑）
                        prev_title_num = prev_last.get('_title_number', '')
                        curr_title_num = curr_first.get('_title_number', '')
                        if prev_title_num and curr_title_num and prev_title_num != curr_title_num:
                            # chunk_id中使用+号（无空格）
                            merged_chunk['_title_number'] = f"{prev_title_num}+{curr_title_num}"
                            # serial_number中使用空格（用于显示）
                            merged_chunk['_title_number_display'] = f"{prev_title_num} + {curr_title_num}"
                        merged_chunk['_is_merged'] = True
                        
                        # 替换上一组的最后一个块
                        final_merged[-1] = merged_chunk
                        # 跳过当前组的第一个块
                        final_merged.extend(group['chunks'][1:])
                    else:
                        final_merged.extend(group['chunks'])
                else:
                    final_merged.extend(group['chunks'])
        
        return final_merged
    
    def merge_within_title(self, title_chunks, max_chunk_size, min_chunk_size):
        """在同一个最低层级标题内合并小块"""
        if not title_chunks:
            return []
        
        merged = []
        i = 0
        
        while i < len(title_chunks):
            current_chunk = title_chunks[i]
            current_content = current_chunk['review_chunk_content']
            
            # 如果当前块是分割块，不参与合并
            if current_chunk.get('is_split', False):
                merged.append(current_chunk)
                i += 1
                continue
            
            # 如果当前块小于最小值，尝试与下一个块合并
            if len(current_content) < min_chunk_size and i + 1 < len(title_chunks):
                next_chunk = title_chunks[i + 1]
                next_content = next_chunk['review_chunk_content']
                
                # 检查是否有公共前缀（防止跨章合并）
                has_common_prefix = self._has_common_prefix(
                    current_chunk.get('section_label', ''),
                    next_chunk.get('section_label', '')
                )
                
                # 检查下一个块是否也是小块且不是分割块，且有公共前缀
                if (has_common_prefix and  # 关键检查：必须有公共前缀
                    not next_chunk.get('is_split', False) and 
                    len(current_content) + len(next_content) <= max_chunk_size):
                    # 合并
                    merged_content = current_content + '\n\n' + next_content
                    merged_chunk = current_chunk.copy()
                    merged_chunk['review_chunk_content'] = merged_content
                    # 使用优化的标签合并函数
                    merged_chunk['section_label'] = self.merge_section_labels(
                        current_chunk['section_label'], 
                        next_chunk['section_label']
                    )
                    merged.append(merged_chunk)
                    i += 2  # 跳过下一个块
                    continue
            
            # 否则直接添加
            merged.append(current_chunk)
            i += 1
        
        return merged
    
    def _has_common_prefix(self, label1, label2):
        """
        检查两个section_label是否有至少一个公共前缀层级
        
        参数:
            label1: 第一个标签，格式如 "第一章工程概况->第五节施工技术保证条件"
            label2: 第二个标签，格式如 "第二章编制依据->第一节编制目的"
            
        返回:
            bool: 如果有至少一个公共前缀层级返回True，否则返回False
        """
        if not label1 or not label2:
            return False
        
        # 如果标签中包含" + "（已经是合并的标签），取第一部分
        if ' + ' in label1:
            label1 = label1.split(' + ')[0]
        if ' + ' in label2:
            label2 = label2.split(' + ')[0]
        
        # 按"->"分割标签
        parts1 = label1.split('->')
        parts2 = label2.split('->')
        
        # 检查第一层级是否相同
        if len(parts1) > 0 and len(parts2) > 0:
            return parts1[0] == parts2[0]
        
        return False
    
    def get_target_level_title(self, section_label, target_level):
        """
        从section_label中提取指定层级的标题
        
        参数:
            section_label: 完整的层级路径字符串，格式如 "一级标题->二级标题->三级标题"
            target_level: 目标层级（1为第一级）
            
        返回:
            str: 指定层级的标题，如果未找到则返回None
        """
        if not section_label:
            return None
        
        # 处理合并的情况（用" + "连接），取第一部分
        if ' + ' in section_label:
            section_label = section_label.split(' + ')[0]
        
        # 按"->"分割层级路径
        parts = section_label.split('->')
        
        # section_label的第一部分就是指定层级（target_level）的标题
        # 因为在split_by_hierarchy中，我们是对每个target_level的标题进行处理
        if len(parts) > 0:
            return parts[0]
        
        return None
    
    def merge_section_labels(self, label1, label2):
        """
        合并两个section_label，提取公共前缀
        
        例如：
        "1 工程概况->1.3 工程地质" + "1 工程概况->1.4 气象水文"
        => "1 工程概况->1.3 工程地质 + 1.4 气象水文"
        
        参数:
            label1: 第一个标签
            label2: 第二个标签
            
        返回:
            str: 合并后的标签
        """
        # 按"->"分割标签
        parts1 = label1.split('->')
        parts2 = label2.split('->')
        
        # 找到公共前缀
        common_prefix = []
        for i in range(min(len(parts1), len(parts2))):
            if parts1[i] == parts2[i]:
                common_prefix.append(parts1[i])
            else:
                break
        
        # 如果有公共前缀
        if common_prefix:
            # 获取不同的部分
            diff1 = '->'.join(parts1[len(common_prefix):])
            diff2 = '->'.join(parts2[len(common_prefix):])
            
            # 构建合并后的标签
            prefix = '->'.join(common_prefix)
            if diff1 and diff2:
                return f"{prefix}->{diff1} + {diff2}"
            elif diff1:
                return f"{prefix}->{diff1}"
            elif diff2:
                return f"{prefix}->{diff2}"
            else:
                return prefix
        else:
            # 没有公共前缀，直接用+连接
            return f"{label1} + {label2}"


