"""Split text into overlapping chunks for embedding.

Packs paragraphs up to a character budget, keeping a small overlap between
consecutive chunks so context is not lost at boundaries. A single oversized
paragraph is hard-split.
"""

from __future__ import annotations

import re

DEFAULT_CHUNK_SIZE = 1000
DEFAULT_OVERLAP = 150

_PARAGRAPH_RE = re.compile(r"\n\s*\n")


def _hard_split(text: str, size: int) -> list[str]:
    return [text[i : i + size] for i in range(0, len(text), size)]


def chunk_text(
    text: str, *, chunk_size: int = DEFAULT_CHUNK_SIZE, overlap: int = DEFAULT_OVERLAP
) -> list[str]:
    text = text.strip()
    if not text:
        return []

    paragraphs: list[str] = []
    for para in _PARAGRAPH_RE.split(text):
        para = para.strip()
        if not para:
            continue
        if len(para) > chunk_size:
            paragraphs.extend(_hard_split(para, chunk_size))
        else:
            paragraphs.append(para)

    chunks: list[str] = []
    current = ""
    for para in paragraphs:
        candidate = f"{current}\n\n{para}" if current else para
        if len(candidate) > chunk_size and current:
            chunks.append(current)
            tail = current[-overlap:] if overlap else ""
            current = f"{tail}\n\n{para}" if tail else para
        else:
            current = candidate
    if current:
        chunks.append(current)
    return chunks
