"""Découpage du texte en extraits indexables — pur et testé.

Paragraphes regroupés jusqu'à ~350 caractères, avec un chevauchement de
queue pour ne pas couper une prescription en deux. Un extrait trop long est
scindé sur les phrases.

Le grain est court À DESSEIN (recette R5) : sur des pages entières, la phrase
qui répond se noie dans son contexte et les scores question→passage ne
séparent plus le pertinent du voisin de domaine ; à ~350 caractères, la marge
revient — et l'extrait cité à l'écran reste lisible d'un coup d'œil.
"""

import re

TAILLE_CIBLE = 350
CHEVAUCHEMENT = 80
TAILLE_MINIMALE = 40  # en deçà : bruit (titres orphelins, numéros de page)


def _phrases(texte: str) -> list[str]:
    return [p.strip() for p in re.split(r"(?<=[.!?;])\s+", texte) if p.strip()]


def decouper(texte: str) -> list[str]:
    paragraphes = [p.strip() for p in re.split(r"\n\s*\n", texte) if p.strip()]
    extraits: list[str] = []
    courant = ""

    def pousser() -> None:
        nonlocal courant
        nettoye = courant.strip()
        if len(nettoye) >= TAILLE_MINIMALE:
            extraits.append(nettoye)
        courant = ""

    for paragraphe in paragraphes:
        paragraphe = re.sub(r"\s+", " ", paragraphe)
        if len(courant) + len(paragraphe) + 1 > TAILLE_CIBLE and courant:
            queue = courant[-CHEVAUCHEMENT:]
            pousser()
            courant = queue + " "
        while len(paragraphe) > TAILLE_CIBLE:
            phrases = _phrases(paragraphe)
            if len(phrases) <= 1:
                courant += paragraphe[:TAILLE_CIBLE]
                paragraphe = paragraphe[TAILLE_CIBLE - CHEVAUCHEMENT :]
                pousser()
                continue
            morceau = ""
            while phrases and len(morceau) + len(phrases[0]) + 1 <= TAILLE_CIBLE:
                morceau += phrases.pop(0) + " "
            courant += morceau
            pousser()
            paragraphe = " ".join(phrases)
        courant += paragraphe + " "
    pousser()
    return extraits
