import logging
import os
import warnings
from typing import Final

from dotenv import load_dotenv


load_dotenv()

GEMINI_MODEL_DEFAULT: Final[str] = "gemini-2.5-flash"
LEGACY_GROQ_MODEL_DEFAULT: Final[str] = "llama-3.1-8b-instant"


# Third-party warnings known on Python 3.14 with current LangChain stack.
warnings.filterwarnings(
    "ignore",
    message=r"Core Pydantic V1 functionality isn't compatible with Python 3\.14 or greater\.",
    category=UserWarning,
)
warnings.filterwarnings(
    "ignore",
    message=r"Valid config keys have changed in V2:.*allow_population_by_field_name.*",
    category=UserWarning,
)

# Reduce noisy model startup output from HF/transformers stack.
os.environ.setdefault("TOKENIZERS_PARALLELISM", "false")
os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")
os.environ.setdefault("TRANSFORMERS_VERBOSITY", "error")
logging.getLogger("transformers").setLevel(logging.ERROR)
logging.getLogger("sentence_transformers").setLevel(logging.ERROR)


def _normalize_gemini_env_vars() -> None:
    """Use a single Gemini API env var name to avoid duplicate-key warnings."""
    gemini_api_key = os.getenv("GEMINI_API_KEY")
    google_api_key = os.getenv("GOOGLE_API_KEY")

    if gemini_api_key and google_api_key:
        # The app uses GEMINI_API_KEY explicitly.
        os.environ.pop("GOOGLE_API_KEY", None)
        return
    if google_api_key and not gemini_api_key:
        os.environ["GEMINI_API_KEY"] = google_api_key


_normalize_gemini_env_vars()


def _env_flag(name: str, default: str = "false") -> bool:
    return os.getenv(name, default).strip().lower() in {"1", "true", "yes", "on"}


class Config:
    DATABASE_URL = os.getenv("DATABASE_URL", "mongodb://localhost:27017")
    REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379")
    MONGO_URI = os.getenv("MONGO_URI", "mongodb://localhost:27017")
    DB_NAME = os.getenv("DB_NAME", "Epicrisis")
    COLLECTION_NAME = os.getenv("COLLECTION_NAME", "HistoriaClinica")
    SECRET_KEY = os.getenv("SECRET_KEY", "cidti40")
    GROQ_API_KEY = os.getenv("GROQ_API_KEY")
    GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
    GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")

    # Modelos configurables por entorno
    LEGACY_LLM_PROVIDERS_ENABLED = _env_flag("LEGACY_LLM_PROVIDERS_ENABLED", "false")
    LLM_PROVIDER = os.getenv("LLM_PROVIDER", "gemini").lower()
    GEMINI_MODEL_DEFAULT = os.getenv("GEMINI_MODEL_DEFAULT", GEMINI_MODEL_DEFAULT)
    GEMINI_MODEL_HISTORIA = os.getenv("GEMINI_MODEL_HISTORIA", GEMINI_MODEL_DEFAULT)
    GEMINI_MODEL_EXTRACT_LOW_RISK = os.getenv(
        "GEMINI_MODEL_EXTRACT_LOW_RISK",
        os.getenv("GEMINI_MODEL_EXTRACT", "gemini-2.5-flash-lite"),
    )
    GEMINI_MODEL_EXTRACT_HIGH_RISK = os.getenv("GEMINI_MODEL_EXTRACT_HIGH_RISK", GEMINI_MODEL_DEFAULT)
    GEMINI_MODEL_EXTRACT = GEMINI_MODEL_EXTRACT_LOW_RISK
    GEMINI_MODEL_REASONING = os.getenv("GEMINI_MODEL_REASONING", GEMINI_MODEL_DEFAULT)
    GEMINI_MODEL_ESCALATION = os.getenv("GEMINI_MODEL_ESCALATION", "gemini-2.5-pro")
    CLINICAL_EXTRACT_HIGH_RISK_TYPES = os.getenv("CLINICAL_EXTRACT_HIGH_RISK_TYPES", "factura")
    CLINICAL_EXTRACT_HISTORIA_HIGH_RISK_CHARS = int(
        os.getenv("CLINICAL_EXTRACT_HISTORIA_HIGH_RISK_CHARS", "8000")
    )
    CLINICAL_EXTRACT_QUIRURGICO_HIGH_RISK_CHARS = int(
        os.getenv("CLINICAL_EXTRACT_QUIRURGICO_HIGH_RISK_CHARS", "5000")
    )
    CLINICAL_EXTRACT_QUIRURGICO_KEYWORD_THRESHOLD = int(
        os.getenv("CLINICAL_EXTRACT_QUIRURGICO_KEYWORD_THRESHOLD", "4")
    )
    GROQ_MODEL_DEFAULT = os.getenv("GROQ_MODEL_DEFAULT", LEGACY_GROQ_MODEL_DEFAULT)
    GROQ_MODEL_CLINICAL = os.getenv("GROQ_MODEL_CLINICAL", LEGACY_GROQ_MODEL_DEFAULT)
    GROQ_MODEL_SOAT = os.getenv("GROQ_MODEL_SOAT", LEGACY_GROQ_MODEL_DEFAULT)
    GROQ_MODEL_CIE10 = os.getenv("GROQ_MODEL_CIE10", LEGACY_GROQ_MODEL_DEFAULT)
    GROQ_MODEL_CUPS = os.getenv("GROQ_MODEL_CUPS", LEGACY_GROQ_MODEL_DEFAULT)
    GROQ_MODEL_RESUMEN = os.getenv("GROQ_MODEL_RESUMEN", LEGACY_GROQ_MODEL_DEFAULT)
    GROQ_MODEL_HISTORIA = os.getenv("GROQ_MODEL_HISTORIA", LEGACY_GROQ_MODEL_DEFAULT)
    GROQ_MODEL_HISTORIA_LIGHT = os.getenv("GROQ_MODEL_HISTORIA_LIGHT", "llama-3.1-8b-instant")
    GROQ_MODEL_LLM1 = os.getenv("GROQ_MODEL_LLM1", LEGACY_GROQ_MODEL_DEFAULT)
    OPENAI_STUB_ENABLED = _env_flag("OPENAI_STUB_ENABLED", "false")
    HISTORIA_MAX_CHARS = int(os.getenv("HISTORIA_MAX_CHARS", "20000"))
    HISTORIA_COMPACT_MAX_CHARS = int(os.getenv("HISTORIA_COMPACT_MAX_CHARS", "16000"))
    HISTORIA_SUMMARY_THRESHOLD = int(os.getenv("HISTORIA_SUMMARY_THRESHOLD", "12000"))
    HISTORIA_SUMMARY_CHUNK = int(os.getenv("HISTORIA_SUMMARY_CHUNK", "40000"))
    HISTORIA_SUMMARY_CHUNK_OVERLAP = int(os.getenv("HISTORIA_SUMMARY_CHUNK_OVERLAP", "800"))
    HISTORIA_SUMMARY_REDUCE_MAX_CHARS = int(os.getenv("HISTORIA_SUMMARY_REDUCE_MAX_CHARS", "40000"))
    HISTORIA_SUMMARY_MAX_RETRIES = int(os.getenv("HISTORIA_SUMMARY_MAX_RETRIES", "2"))
    HISTORIA_SUMMARY_TARGET_RATIO = float(os.getenv("HISTORIA_SUMMARY_TARGET_RATIO", "0.10"))
    HISTORIA_SUMMARY_LONG_MIN_WORDS = int(os.getenv("HISTORIA_SUMMARY_LONG_MIN_WORDS", "350"))
    HISTORIA_SUMMARY_MAX_WORDS = int(os.getenv("HISTORIA_SUMMARY_MAX_WORDS", "700"))
    HISTORIA_SUMMARY_QUALITY_RETRIES = int(os.getenv("HISTORIA_SUMMARY_QUALITY_RETRIES", "1"))
    HISTORIA_ANTECEDENTS_QUALITY_RETRIES = int(
        os.getenv("HISTORIA_ANTECEDENTS_QUALITY_RETRIES", "1")
    )
    HISTORIA_SUMMARY_RETRY_DELAYS_SECONDS = os.getenv(
        "HISTORIA_SUMMARY_RETRY_DELAYS_SECONDS",
        "2,5",
    )
    HISTORIA_LARGE_THRESHOLD = int(os.getenv("HISTORIA_LARGE_THRESHOLD", "18000"))
    SOAT_RAG_PRIMARY_K = int(os.getenv("SOAT_RAG_PRIMARY_K", "6"))
    SOAT_RAG_CODE_K = int(os.getenv("SOAT_RAG_CODE_K", "4"))
    SOAT_RAG_DESC_K = int(os.getenv("SOAT_RAG_DESC_K", "4"))
    SOAT_RAG_MAX_EVIDENCE = int(os.getenv("SOAT_RAG_MAX_EVIDENCE", "8"))
    SOAT_RAG_MAX_EXTRACT_CHARS = int(os.getenv("SOAT_RAG_MAX_EXTRACT_CHARS", "900"))
    SOAT_PROMPT_MAX_CIE10 = int(os.getenv("SOAT_PROMPT_MAX_CIE10", "8"))
    SOAT_PROMPT_MAX_CUPS = int(os.getenv("SOAT_PROMPT_MAX_CUPS", "8"))
    CIE10_RESOLUTION_K = int(os.getenv("CIE10_RESOLUTION_K", "12"))
    LLM_CACHE_ENABLED = _env_flag("LLM_CACHE_ENABLED", "true")
    LLM_TASK_CACHE_COLLECTION = os.getenv("LLM_TASK_CACHE_COLLECTION", "llm_task_cache")
    LLM_CACHE_RETENTION_DAYS = int(os.getenv("LLM_CACHE_RETENTION_DAYS", "30"))
    LLM_CACHE_VERSION = os.getenv("LLM_CACHE_VERSION", "v1")
    DEMO_ANONYMIZATION_ENABLED = _env_flag("DEMO_ANONYMIZATION_ENABLED", "false")
    DEMO_IDENTITY_COLLECTION = os.getenv("DEMO_IDENTITY_COLLECTION", "demo_identity_aliases")
    AUDIT_LOG_ENABLED = os.getenv("AUDIT_LOG_ENABLED", "true")
    AUDIT_LOG_FILE = os.getenv("AUDIT_LOG_FILE", "logs/audit.jsonl")
    AUDIT_LOG_LEVEL = os.getenv("AUDIT_LOG_LEVEL", "INFO")
    AUDIT_MONGO_ENABLED = os.getenv("AUDIT_MONGO_ENABLED", "true")
    AUDIT_RETENTION_DAYS = int(os.getenv("AUDIT_RETENTION_DAYS", "180"))


config = Config()


def require_env(value: str | None, name: str) -> str:
    if not value:
        raise RuntimeError(f"Falta la variable de entorno requerida: {name}")
    return value
