"""Embedding model management — save, load, and encode with multilingual-e5-small."""

import os

from sentence_transformers import SentenceTransformer


def embedding_save_model(model_id: str, path: str) -> str:
    """Descarga modelo de HuggingFace y lo guarda en path local.

    Args:
        model_id: ID del modelo en HuggingFace (ej: "intfloat/multilingual-e5-small").
        path: Directorio destino para guardar el modelo.

    Returns:
        Path absoluto donde se guardo el modelo.

    Raises:
        OSError: Si no se puede escribir en el path.
        Exception: Si el modelo no existe en HuggingFace.
    """
    os.makedirs(path, exist_ok=True)
    model = SentenceTransformer(model_id)
    model.save(path)
    return os.path.abspath(path)


def embedding_load_model(path: str) -> SentenceTransformer:
    """Carga modelo de embeddings desde path local.

    Args:
        path: Directorio con el modelo guardado por embedding_save_model.

    Returns:
        Instancia de SentenceTransformer lista para encode.

    Raises:
        OSError: Si el path no existe o no contiene un modelo valido.
    """
    return SentenceTransformer(path)


def embedding_encode(model: SentenceTransformer, texts: list, mode: str = "document") -> list:
    """Genera embeddings normalizados para una lista de textos.

    Aplica automaticamente los prefijos requeridos por modelos e5:
    - mode="document" -> "passage: " prefix
    - mode="query"    -> "query: " prefix

    Args:
        model: Modelo cargado con embedding_load_model.
        texts: Lista de strings a codificar.
        mode: "document" para indexar, "query" para buscar.

    Returns:
        Lista de arrays numpy float32 normalizados (dim depende del modelo).

    Raises:
        ValueError: Si mode no es "document" ni "query".
    """
    if mode not in ("document", "query"):
        raise ValueError(f"mode must be 'document' or 'query', got '{mode}'")

    prefix = "passage: " if mode == "document" else "query: "
    prefixed = [f"{prefix}{t}" for t in texts]
    embeddings = model.encode(prefixed, normalize_embeddings=True, show_progress_bar=False)
    return embeddings
