"""
Bot update dispatcher.

This module owns the Telegram Application instance and routes
incoming updates to the correct handler.
"""
from __future__ import annotations

import hmac
import hashlib

import structlog
from telegram import Update
from telegram.ext import Application, CallbackQueryHandler, CommandHandler, MessageHandler, filters

from app.bot.handlers import callback, command, message
from app.bot.session import SessionManager
from app.config import Settings

log = structlog.get_logger(__name__)


def validate_webhook_secret(secret_header: str | None, expected: str) -> bool:
    """Timing-safe comparison of Telegram's secret token."""
    if not secret_header:
        return False
    return hmac.compare_digest(secret_header, expected)


def build_application(settings: Settings) -> Application:
    """Build and return the Telegram Application (does not start polling)."""
    app = (
        Application.builder()
        .token(settings.telegram_bot_token.get_secret_value())
        .build()
    )
    return app


def register_handlers(app: Application) -> None:
    """Register all command and message handlers."""
    # Commands
    app.add_handler(CommandHandler("start", _wrap(command.handle_start)))
    app.add_handler(CommandHandler("help", _wrap(command.handle_help)))
    app.add_handler(CommandHandler("lang", _wrap(command.handle_lang)))
    app.add_handler(CommandHandler("search", _wrap(command.handle_search_command)))
    app.add_handler(CommandHandler("recent", _wrap(command.handle_recent)))
    app.add_handler(CommandHandler("stats", _wrap(command.handle_stats)))

    # Plain text messages (URLs and search queries)
    app.add_handler(
        MessageHandler(filters.TEXT & ~filters.COMMAND, _wrap_message(message.handle_message))
    )

    # Inline keyboard callbacks
    app.add_handler(CallbackQueryHandler(_wrap_callback(callback.handle_callback)))


def _wrap(handler: object) -> object:
    """
    Dependency injection wrapper for command handlers.
    In production this is wired properly via the webhook route;
    here we return the handler as-is for registration purposes.
    The actual DI happens in the webhook FastAPI route.
    """
    return handler


def _wrap_message(handler: object) -> object:
    return handler


def _wrap_callback(handler: object) -> object:
    return handler
