#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
@Project   : lq-agent-api
@File      : text_split.py
@IDE       : Cursor
@Author    : AI Assistant
@Date      : 2025-12-26
@Description: 文本切割工具函数，用于将长文本切分为合适长度的片段
"""

import re
from typing import List


def split_text(raw_content: str, min_length: int = 150, target_length: int = 250) -> List[str]:
    """
    将输入的中文字符串切分为指定长度范围的小片段
    
    算法逻辑：
    1. 首先按照中文标点符号（。！？；）和换行符将文本分割成句子
    2. 然后将句子组合成片段，每个片段至少min_length字，目标target_length字
    3. 如果最后一段文本低于min_length字，则合并到倒数第二段中
    
    Args:
        raw_content (str): 原始文本内容
        min_length (int): 每段最小字数，默认150字
        target_length (int): 每段目标字数，默认250字
        
    Returns:
        List[str]: 切分后的文本片段列表
        
    Examples:
        >>> text = "这是第一句话。这是第二句话！这是第三句话？" * 100
        >>> segments = split_text(text, min_length=150, target_length=250)
        >>> all(len(seg) >= 150 for seg in segments)
        True
    """
    if not raw_content or not raw_content.strip():
        return []
    
    # 按标点分句分段
    pattern = re.compile(r'([^。！？；\n]+[。！？；\n]?)')
    sentences = pattern.findall(raw_content)
    raw_list = [s.strip() for s in sentences if s.strip()]
    
    if not raw_list:
        return [raw_content.strip()] if raw_content.strip() else []
    
    # 组合句子成片段
    segments = []
    current_segment = ""
    
    for sentence in raw_list:
        # 如果当前片段为空，直接添加句子
        if not current_segment:
            current_segment = sentence
        else:
            # 计算添加新句子后的长度
            potential_length = len(current_segment) + len(sentence)
            
            # 如果当前片段已达到最小长度，且添加新句子会超过目标长度
            if len(current_segment) >= min_length and potential_length > target_length:
                # 保存当前片段，开始新片段
                segments.append(current_segment)
                current_segment = sentence
            else:
                # 继续添加到当前片段
                current_segment += sentence
    
    # 处理最后一个片段
    if current_segment:
        # 如果最后一段低于最小长度，且已有其他片段，则合并到倒数第二段
        if len(current_segment) < min_length and len(segments) > 0:
            segments[-1] += current_segment
        else:
            segments.append(current_segment)
    
    return segments


def split_text_with_overlap(raw_content: str, min_length: int = 150, 
                           target_length: int = 250, overlap: int = 50) -> List[str]:
    """
    将输入的中文字符串切分为指定长度范围的小片段，支持片段间重叠
    
    Args:
        raw_content (str): 原始文本内容
        min_length (int): 每段最小字数，默认150字
        target_length (int): 每段目标字数，默认250字
        overlap (int): 片段间重叠字数，默认50字
        
    Returns:
        List[str]: 切分后的文本片段列表
    """
    if not raw_content or not raw_content.strip():
        return []
    
    # 首先使用基础切分
    base_segments = split_text(raw_content, min_length, target_length)
    
    if overlap <= 0 or len(base_segments) <= 1:
        return base_segments
    
    # 添加重叠部分
    overlapped_segments = []
    for i, segment in enumerate(base_segments):
        if i == 0:
            overlapped_segments.append(segment)
        else:
            # 从前一个片段取最后overlap个字符作为重叠
            prev_segment = base_segments[i - 1]
            overlap_text = prev_segment[-overlap:] if len(prev_segment) >= overlap else prev_segment
            overlapped_segments.append(overlap_text + segment)
    
    return overlapped_segments


if __name__ == "__main__":
    # 测试代码
    test_text = """
    建筑工程施工质量验收统一标准是建筑工程质量管理的重要依据。本标准适用于建筑工程施工质量的验收，并作为建筑工程各专业工程施工质量验收规范的统一准则。
    建筑工程施工应符合工程勘察、设计文件的要求。参加工程施工质量验收的各方人员应具备规定的资格。工程质量的验收均应在施工单位自行检查评定的基础上进行。
    隐蔽工程在隐蔽前应由施工单位通知有关单位进行验收，并应形成验收文件。涉及结构安全的试块、试件以及有关材料，应按规定进行见证取样检测。
    检验批的质量应按主控项目和一般项目验收。对涉及结构安全和使用功能的重要分部工程应进行抽样检测。承担见证取样检测及有关结构安全检测的单位应具有相应资质。
    工程的观感质量应由验收人员通过现场检查，并应共同确认。通过返修或加固处理仍不能满足安全使用要求的分部工程、单位工程，严禁验收。
    """ * 3
    
    print("原始文本长度:", len(test_text))
    print("\n" + "="*50)
    
    segments = split_text(test_text, min_length=150, target_length=250)
    print(f"\n切分结果：共 {len(segments)} 个片段")
    print("="*50)
    
    for i, seg in enumerate(segments, 1):
        print(f"\n片段 {i} (长度: {len(seg)} 字):")
        print(seg)

