from __future__ import annotations

from dataclasses import dataclass

from app.config import config


_HISTORIA_ANCHORS = (
    "nombre del paciente",
    "motivo de consulta",
    "diagnost",
    "proced",
    "medic",
    "fecha ingreso",
)
_QUIRURGICO_KEYWORDS = (
    "procedimiento",
    "quirurg",
    "diagnost",
    "hallaz",
    "postoperator",
    "preoperator",
    "complic",
)


@dataclass(frozen=True, slots=True)
class ClinicalExtractionPolicyDecision:
    document_type: str
    risk_level: str
    reason_codes: tuple[str, ...]

    @property
    def is_high_risk(self) -> bool:
        return self.risk_level == "high"


def decide_clinical_extraction_policy(
    *,
    document_type: str,
    raw_text: str,
    summary_text: str | None = None,
) -> ClinicalExtractionPolicyDecision:
    normalized_type = str(document_type or "generico").strip().lower() or "generico"
    source_text = str(summary_text or raw_text or "")
    normalized_source = source_text.casefold()
    high_risk_types = {
        item.strip().lower()
        for item in str(config.CLINICAL_EXTRACT_HIGH_RISK_TYPES or "").split(",")
        if item.strip()
    }
    reason_codes: list[str] = []

    if normalized_type in high_risk_types:
        reason_codes.append("document_type_high_risk")

    if normalized_type == "historia_clinica":
        if len(str(raw_text or "")) >= int(config.CLINICAL_EXTRACT_HISTORIA_HIGH_RISK_CHARS or 0):
            reason_codes.append("historia_long_context")
        anchor_hits = sum(1 for token in _HISTORIA_ANCHORS if token in normalized_source)
        if anchor_hits < 3:
            reason_codes.append("historia_sparse_anchors")
    elif normalized_type == "quirurgico":
        if len(source_text) >= int(config.CLINICAL_EXTRACT_QUIRURGICO_HIGH_RISK_CHARS or 0):
            reason_codes.append("quirurgico_long_context")
        keyword_hits = sum(normalized_source.count(token) for token in _QUIRURGICO_KEYWORDS)
        if keyword_hits >= int(config.CLINICAL_EXTRACT_QUIRURGICO_KEYWORD_THRESHOLD or 0):
            reason_codes.append("quirurgico_dense_keywords")

    risk_level = "high" if reason_codes else "low"
    return ClinicalExtractionPolicyDecision(
        document_type=normalized_type,
        risk_level=risk_level,
        reason_codes=tuple(reason_codes),
    )
