from __future__ import annotations

import re
import unicodedata


_PRIORITY_SECTION_PATTERN = re.compile(
    r"\b(?:an[aá]lisis\s+y\s+plan|evoluci[oó]n\s+m[eé]dica|plan(?:\s+de)?\s+egreso|egreso\s+m[eé]dico)\b",
    re.IGNORECASE,
)
_FORMULATION_SECTION_PATTERN = re.compile(
    r"\b(?:f[oó]rmula\s+(?:m[eé]dica|de\s+egreso)|medicamentos?\s+formulados?|tratamiento\s+al\s+egreso)\b",
    re.IGNORECASE,
)
_MEDICATION_DETAIL_PATTERN = re.compile(
    r"\b(?:mg|mcg|g|ml|tabletas?|c[aá]psulas?|ampollas?|cada\s+\d+\s+horas?|por\s+\d+\s+d[ií]as?)\b",
    re.IGNORECASE,
)
_ALARM_SECTION_PATTERN = re.compile(r"\bsignos?\s+de\s+alarma\b", re.IGNORECASE)
_ALARM_SYMPTOM_PATTERN = re.compile(
    r"\b(?:fiebre|dolor\s+(?:intenso|progresivo)|sangrado|secreci[oó]n|disnea|"
    r"dificultad\s+respiratoria|enrojecimiento|inflamaci[oó]n)\b",
    re.IGNORECASE,
)
_CONCRETE_RECOMMENDATION_PATTERN = re.compile(
    r"\b(?:"
    r"incapacidad(?:\s+(?:m[eé]dica|laboral))?\s*[:;-]?(?:\s+por)?\s+\d+|"
    r"(?:continuar|formular|f[oó]rmula|prescribir|tomar|aplicar)\b.{0,90}\b(?:mg|mcg|g|ml|tabletas?|"
    r"c[aá]psulas?|cada\s+\d+\s+horas?|por\s+\d+\s+d[ií]as?)|"
    r"(?:control|cita|seguimiento)\s+(?:por|con|en)\b|"
    r"(?:rehabilitaci[oó]n|fisioterapia|terapia\s+f[ií]sica)\b|"
    r"(?:curaci[oó]n|retiro\s+de\s+puntos)\b|"
    r"(?:usar|mantener|continuar\s+con)\b.{0,60}\b(?:cabestrillo|f[eé]rula|inmovilizador|vendaje)\b|"
    r"(?:cabestrillo|f[eé]rula|inmovilizador)\b.{0,60}\b(?:por|durante|hasta|permanente|continuo)\b|"
    r"(?:no\s+(?:apoyar|realizar\s+(?:actividad|esfuerzo))|evitar\s+(?:cargar|esfuerzo|actividad)|"
    r"restricci[oó]n\s+(?:laboral|f[ií]sica)|"
    r"sin\s+apoyo|reposo\s+(?:absoluto|relativo))\b|"
    r"(?:consultar|regresar|acudir)\b.{0,100}\b(?:fiebre|dolor|sangrado|secreci[oó]n|disnea|"
    r"dificultad\s+respiratoria|enrojecimiento|inflamaci[oó]n)\b"
    r")",
    re.IGNORECASE,
)
_COMPLETED_CARE_PATTERN = re.compile(
    r"\b(?:se\s+(?:administr[oó]|aplic[oó]|realiz[oó]|retir[oó])|recibi[oó]|complet[oó]|"
    r"procedimiento\s+(?:realizado|finalizado)|"
    r"tratamiento\s+(?:completado|finalizado))\b",
    re.IGNORECASE,
)
_SECTION_END_PATTERN = re.compile(
    r"^(?:antecedentes|diagn[oó]sticos?|procedimientos?|examen\s+f[ií]sico|hallazgos?|laboratorios?)\b",
    re.IGNORECASE,
)


def _clean(value: str) -> str:
    return re.sub(r"\s+", " ", str(value or "")).strip()


def _key(value: str) -> str:
    normalized = unicodedata.normalize("NFKD", _clean(value))
    return "".join(char for char in normalized if not unicodedata.combining(char)).casefold()


def extract_historia_recommendation_fragments(
    raw_text: str,
    *,
    max_fragments: int = 40,
) -> list[str]:
    """Recorre todas las páginas y conserva contexto breve de indicaciones concretas."""

    prioritized: list[tuple[int, int, str]] = []
    sequence = 0
    for page_number, page_text in enumerate(re.split(r"\f", str(raw_text or "")), start=1):
        lines = [_clean(line) for line in page_text.splitlines()]
        in_priority_section = False
        in_formulation_section = False
        in_alarm_section = False
        for line in lines:
            if not line:
                in_priority_section = False
                in_formulation_section = False
                in_alarm_section = False
                continue
            if _PRIORITY_SECTION_PATTERN.search(line):
                in_priority_section = True
            elif in_priority_section and _SECTION_END_PATTERN.match(line):
                in_priority_section = False
            if _FORMULATION_SECTION_PATTERN.search(line):
                in_formulation_section = True
                continue
            if _ALARM_SECTION_PATTERN.search(line):
                in_alarm_section = True
                if not _ALARM_SYMPTOM_PATTERN.search(line):
                    continue
            if in_formulation_section and _SECTION_END_PATTERN.match(line):
                in_formulation_section = False
            if in_alarm_section and _SECTION_END_PATTERN.match(line):
                in_alarm_section = False
            is_concrete = bool(_CONCRETE_RECOMMENDATION_PATTERN.search(line))
            is_formula_detail = bool(in_formulation_section and _MEDICATION_DETAIL_PATTERN.search(line))
            is_concrete_alarm = bool(in_alarm_section and _ALARM_SYMPTOM_PATTERN.search(line))
            if not is_concrete and not is_formula_detail and not is_concrete_alarm:
                continue
            context = line
            if not context or _COMPLETED_CARE_PATTERN.search(context):
                continue
            priority = 0 if in_priority_section or in_formulation_section or in_alarm_section else 1
            prioritized.append((priority, sequence, f"[página {page_number}] {context}"))
            sequence += 1

    selected: list[str] = []
    seen: set[str] = set()
    for _priority, _sequence, fragment in sorted(prioritized, key=lambda item: (item[0], item[1])):
        fragment_key = _key(re.sub(r"^\[página \d+\]\s*", "", fragment, flags=re.IGNORECASE))
        if fragment_key in seen:
            continue
        seen.add(fragment_key)
        selected.append(fragment)
        if len(selected) >= max(1, max_fragments):
            break
    return selected


def build_historia_recommendation_context(
    raw_text: str,
    *,
    max_characters: int = 10000,
) -> str:
    fragments = extract_historia_recommendation_fragments(raw_text)
    return "\n".join(fragments)[: max(500, max_characters)]


def has_concrete_historia_recommendations(raw_text: str) -> bool:
    return bool(extract_historia_recommendation_fragments(raw_text, max_fragments=1))
