"""Telegram webhook endpoint."""
from __future__ import annotations

import hmac

import structlog
import structlog.contextvars
from fastapi import APIRouter, Depends, Header, HTTPException, Request, status
from telegram import Update

from app.config import Settings
from app.dependencies import get_bot_app, get_queue, get_redis, get_settings, get_db_session

log = structlog.get_logger(__name__)
router = APIRouter()


@router.post("/webhook")
async def telegram_webhook(
    request: Request,
    x_telegram_bot_api_secret_token: str | None = Header(default=None),
    settings: Settings = Depends(get_settings),
    bot_app=Depends(get_bot_app),
) -> dict:
    """
    Receive Telegram updates via webhook.

    Security: validates X-Telegram-Bot-Api-Secret-Token header
    using timing-safe comparison before processing any data.
    """
    expected = settings.telegram_webhook_secret.get_secret_value()

    if not x_telegram_bot_api_secret_token or not hmac.compare_digest(
        x_telegram_bot_api_secret_token, expected
    ):
        log.warning(
            "webhook.auth_failed",
            ip=request.client.host if request.client else "unknown",
        )
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Forbidden")

    body = await request.json()
    structlog.contextvars.bind_contextvars(
        update_id=body.get("update_id", "?")
    )

    try:
        update = Update.de_json(body, bot_app.bot)
        async with bot_app:
            await bot_app.process_update(update)
    except Exception as exc:
        # Always return 200 to Telegram so it does not retry indefinitely
        log.error("webhook.process_error", error=str(exc), exc_info=True)

    structlog.contextvars.unbind_contextvars("update_id")
    # Telegram requires 200 OK — even on processing errors
    return {"ok": True}
