"""Telegram bot: answers user questions using RAG (retrieval + GigaChat)."""

from __future__ import annotations

import asyncio
import logging
import os
from pathlib import Path

from dotenv import load_dotenv

_repo_root = Path(__file__).resolve().parent.parent
load_dotenv(_repo_root / ".env")

logger = logging.getLogger(__name__)

# Расширенное логирование: входящие сообщения, число эмбеддингов, число чанков из БД, ответ LLM.
# Включить/выключить: RAG_BOT_VERBOSE_LOGGING=true|false (по умолчанию true для отладки).
VERBOSE_LOGGING_MAX_ANSWER_CHARS = 500


def _verbose_logging_enabled() -> bool:
    return os.getenv("RAG_BOT_VERBOSE_LOGGING", "true").lower() in ("1", "true", "yes")


def _run_rag(
    question: str,
    top_k: int = 5,
    story_id: int | None = None,
    with_stats: bool = False,
) -> str | tuple[str, dict]:
    """Synchronous RAG call: retrieval + LLM. Used from thread.
    If with_stats=True, returns (answer, stats); else returns answer only.
    """
    from rag_agent.config import load_config
    from rag_agent.index.embeddings import get_embedding_client
    from rag_agent.index.postgres import connect, ensure_schema
    from rag_agent.agent.pipeline import answer_query, answer_query_with_stats, get_llm_client

    config = load_config()
    conn = connect(config.db_dsn)
    try:
        ensure_schema(conn, config.embeddings_dim)
        embedding_client = get_embedding_client(config.embeddings_dim)
        llm_client = get_llm_client(config)
        if with_stats:
            return answer_query_with_stats(
                conn,
                config,
                embedding_client,
                llm_client,
                question,
                top_k=top_k,
                story_id=story_id,
            )
        return answer_query(
            conn,
            config,
            embedding_client,
            llm_client,
            question,
            top_k=top_k,
            story_id=story_id,
        )
    finally:
        conn.close()


def run_bot() -> None:
    token = os.getenv("TELEGRAM_BOT_TOKEN", "").strip()
    if not token:
        logger.error(
            "TELEGRAM_BOT_TOKEN is required. Set it in .env or environment. "
            "Container will stay up; restart after setting the token."
        )
        import time
        while True:
            time.sleep(3600)

    from telegram import Update
    from telegram.ext import Application, ContextTypes, MessageHandler, filters

    verbose = _verbose_logging_enabled()

    async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
        if not update.message or not update.message.text:
            return
        question = update.message.text.strip()
        if not question:
            await update.message.reply_text("Напишите вопрос текстом.")
            return
        user_id = update.effective_user.id if update.effective_user else None
        chat_id = update.effective_chat.id if update.effective_chat else None
        if verbose:
            logger.info(
                "received message user_id=%s chat_id=%s text=%s",
                user_id,
                chat_id,
                repr(question[:200] + ("…" if len(question) > 200 else "")),
            )
        try:
            loop = asyncio.get_event_loop()
            result = await loop.run_in_executor(
                None,
                lambda: _run_rag(
                    question,
                    top_k=5,
                    story_id=None,
                    with_stats=verbose,
                ),
            )
            if verbose:
                answer, stats = result
                logger.info(
                    "query_embeddings=%s chunks_found=%s",
                    stats["query_embeddings"],
                    stats["chunks_found"],
                )
                answer_preview = stats["answer"]
                if len(answer_preview) > VERBOSE_LOGGING_MAX_ANSWER_CHARS:
                    answer_preview = (
                        answer_preview[:VERBOSE_LOGGING_MAX_ANSWER_CHARS] + "…"
                    )
                logger.info("llm_response=%s", repr(answer_preview))
            else:
                answer = result
            if len(answer) > 4096:
                answer = answer[:4090] + "\n…"
            await update.message.reply_text(answer)
        except Exception as e:
            logger.exception("RAG error")
            await update.message.reply_text(
                f"Не удалось получить ответ: {e!s}. "
                "Проверьте RAG_DB_DSN и GIGACHAT_CREDENTIALS."
            )

    app = Application.builder().token(token).build()
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
    logger.info("Telegram bot started (polling)")
    app.run_polling(drop_pending_updates=True)


def main() -> None:
    logging.basicConfig(
        format="%(asctime)s %(levelname)s %(name)s %(message)s",
        level=logging.INFO,
    )
    # Убрать из лога пустые HTTP-ответы polling (без сообщений от пользователя)
    for name in ("telegram", "httpx", "httpcore"):
        logging.getLogger(name).setLevel(logging.WARNING)
    try:
        run_bot()
    except KeyboardInterrupt:
        pass
    except ValueError as e:
        raise SystemExit(e) from e
