#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
文本切块工具函数
"""

from typing import Any, Dict, List, Tuple


def _is_markdown_table_line(line: str) -> bool:
    """判断一行是否为 Markdown 表格行（以 | 开头且以 | 结尾）"""
    stripped = line.strip()
    return stripped.startswith('|') and stripped.endswith('|') and len(stripped) >= 3


def _split_text_lines_with_overlap(
    lines: List[str],
    max_chars: int,
    overlap_chars: int
) -> List[List[str]]:
    """
    将文本行列表按字符数切分，相邻 chunk 之间保留重叠。

    - 普通行（<= max_chars）：积累到超限时 flush，下一个 chunk 以末尾若干行作重叠头。
    - 超长行（> max_chars）：先 flush 当前积累，再对该行做字符级滑窗切分，
      每片段 max_chars 字符，步长 max_chars - overlap_chars（即相邻片段重叠 overlap_chars）。
    """
    if not lines:
        return []

    chunks: List[List[str]] = []
    current_lines: List[str] = []
    current_chars: int = 0

    def _flush():
        """保存当前 chunk，并以末尾若干行作为下一个 chunk 的重叠起始。"""
        nonlocal current_lines, current_chars
        if not current_lines:
            return
        chunks.append(list(current_lines))
        overlap_lines: List[str] = []
        overlap_len: int = 0
        for prev in reversed(current_lines):
            overlap_lines.insert(0, prev)
            overlap_len += len(prev)
            if overlap_len >= overlap_chars:
                break
        current_lines = overlap_lines
        current_chars = overlap_len

    for line in lines:
        line_chars = len(line)

        if line_chars > max_chars:
            # 超长行：先 flush，再对该行做字符级滑窗切分
            _flush()
            step = max_chars - overlap_chars  # 滑动步长
            start = 0
            while start < line_chars:
                piece = line[start: start + max_chars]
                chunks.append([piece])
                start += step
            # 以最后一片段末尾的 overlap_chars 个字符作重叠起始
            last_piece = line[max(0, line_chars - overlap_chars):]
            current_lines = [last_piece]
            current_chars = len(last_piece)
        else:
            # 普通行：加入后超限则先 flush
            if current_chars + line_chars > max_chars and current_lines:
                _flush()
            current_lines.append(line)
            current_chars += line_chars

    if current_lines:
        chunks.append(current_lines)

    return chunks


def split_section_into_chunks(
    lines: List[str],
    max_chars: int = 600,
    overlap_chars: int = 30
) -> List[Dict[str, Any]]:
    """
    将二级分类下的行列表切分为 chunks。

    规则：
    - Markdown 表格（以 | 开头且以 | 结尾的连续行）作为独立 chunk，不切断、不与其他内容合并、无重叠。
    - 普通文本按 max_chars 字符数切分，相邻 chunk 之间有 overlap_chars 字符的重叠。
    - 单行超过 max_chars 时做字符级滑窗切分，相邻片段之间同样保留 overlap_chars 重叠。

    Args:
        lines:         行列表（不含行号标记）
        max_chars:     每个文本 chunk 的最大字符数，默认 600
        overlap_chars: 相邻文本 chunk 的重叠字符数，默认 30

    Returns:
        List[Dict]: 每个元素包含：
            - 'type':  'text' 或 'table'
            - 'lines': 该 chunk 对应的行列表
    """
    if not lines:
        return []

    # Step 1：将行序列分割为交替的 table_segment / text_segment
    segments: List[Tuple[str, List[str]]] = []
    i = 0
    while i < len(lines):
        if _is_markdown_table_line(lines[i]):
            table_lines: List[str] = []
            while i < len(lines) and _is_markdown_table_line(lines[i]):
                table_lines.append(lines[i])
                i += 1
            segments.append(('table', table_lines))
        else:
            text_lines: List[str] = []
            while i < len(lines) and not _is_markdown_table_line(lines[i]):
                text_lines.append(lines[i])
                i += 1
            segments.append(('text', text_lines))

    # Step 2：表格段整体输出；文本段按字符数切分并加重叠
    result: List[Dict[str, Any]] = []
    for seg_type, seg_lines in segments:
        if seg_type == 'table':
            result.append({'type': 'table', 'lines': seg_lines})
        else:
            for chunk_lines in _split_text_lines_with_overlap(seg_lines, max_chars, overlap_chars):
                result.append({'type': 'text', 'lines': chunk_lines})

    return result
