"""Motor principal del chatbot conversacional."""

import logging
import sys
from pathlib import Path

import requests

from config import (
    MAX_INPUT_LENGTH,
    MODEL_NAME,
    MSG_EMPTY,
    MSG_FALLBACK,
    MSG_TOO_LONG,
    OLLAMA_BASE_URL,
    SYSTEM_PROMPT,
    TEMPERATURE,
)
from guardrails import check_input, check_output
from memory import ConversationMemory

logger = logging.getLogger(__name__)
memory = ConversationMemory()


def respond(user_message: str, session_id: str = "default") -> str:
    """Procesa un mensaje y devuelve una respuesta de texto."""
    try:
        if user_message is None:
            user_message = ""

        user_message = user_message.strip()
        if not user_message:
            return MSG_EMPTY
        if len(user_message) > MAX_INPUT_LENGTH:
            return MSG_TOO_LONG

        safe, message_or_rejection = check_input(user_message)
        if not safe:
            logger.warning(f"Mensaje bloqueado en sesión '{session_id}'")
            return message_or_rejection

        history = memory.get_history(session_id)

        # Construir lista de mensajes para el LLM
        system_content = SYSTEM_PROMPT
        
        messages = [{"role": "system", "content": system_content}]
        messages.extend(history)
        messages.append({"role": "user", "content": user_message})

        raw_response = _call_ollama(messages)

        safe, final_response = check_output(raw_response)
        if not safe:
            logger.warning(f"Respuesta del LLM rechazada en sesión {session_id}")
            return final_response

        memory.add_turn(session_id, "user", user_message)
        memory.add_turn(session_id, "assistant", final_response)

        logger.info(
            f"Sesión {session_id} | entrada: {len(user_message)} chars | respuesta: {len(final_response)} chars"
        )
        return final_response

    except Exception as exc:
        logger.error(f"Error inesperado en sesión '{session_id}': {exc}", exc_info=True)
        return MSG_FALLBACK


def _call_ollama(messages: list[dict]) -> str:
    """Llama al endpoint /api/chat de Ollama."""
    payload = {
        "model": MODEL_NAME,
        "messages": messages,
        "stream": False,
        "options": {"temperature": TEMPERATURE},
    }
    response = requests.post(
        f"{OLLAMA_BASE_URL}/api/chat",
        json=payload,
        timeout=60,
    )
    response.raise_for_status()
    return response.json()["message"]["content"]


def reset_session(session_id: str) -> None:
    """Limpia el historial de una sesión."""
    memory.clear_session(session_id)
    logger.info(f"Sesión {session_id} reiniciada.")


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, format="%(levelname)s | %(message)s")
    print("Escribe 'salir' para terminar, '/reset' para nueva sesión.\n")

    session = "consola"
    while True:
        user_input = input("Mensaje: ").strip()
        if not user_input:
            continue
        if user_input.lower() == "salir":
            print("Bot: ¡Hasta luego!")
            break
        if user_input.lower() == "/reset":
            reset_session(session)
            print("Bot: Sesión reiniciada. ¿En qué te puedo ayudar?")
            continue

        response = respond(user_input, session_id=session)
        print(f"Bot: {response}")
