"""Application entrypoint (polling only, one instance per bot token)."""

from __future__ import annotations

import asyncio
import logging

from aiogram import Bot
from aiogram.client.default import DefaultBotProperties
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.client.telegram import TelegramAPIServer
from aiogram.types import BotCommand

from app.config import Settings
from app.context import build_context
from app.gateways.base import BotIdentity
from app.gateways.telegram import AiogramGateway
from app.handlers import build_dispatcher
from app.logging_config import setup_logging

logger = logging.getLogger(__name__)

COMMANDS = [
    BotCommand(command="start", description="شروع و دریافت لینک"),
    BotCommand(command="help", description="راهنما"),
    BotCommand(command="id", description="نمایش شناسه کاربر/چت"),
    BotCommand(command="admin", description="پنل مدیریت"),
]


def _session(settings: Settings) -> AiohttpSession:
    kwargs = {
        "proxy": settings.proxy_url,
        "timeout": float(settings.telegram_request_timeout_seconds),
    }

    if settings.telegram_api_base_url:
        return AiohttpSession(
            api=TelegramAPIServer.from_base(settings.telegram_api_base_url),
            **kwargs,
        )

    return AiohttpSession(**kwargs)


async def run() -> None:
    settings = Settings()
    setup_logging(settings.log_level, settings.log_file)

    logger.info("starting telegram media publisher")
    logger.info("configuration: %s", settings.safe_summary())

    if not settings.auto_create_schema:
        logger.info(
            "AUTO_CREATE_SCHEMA=false; expecting Alembic migrations to be applied"
        )

    session = _session(settings)

    bot = Bot(
        token=settings.bot_token.get_secret_value(),
        session=session,
        default=DefaultBotProperties(parse_mode=None),
    )

    ctx = None

    try:
        me = await bot.get_me()
        logger.info("authenticated as @%s (id=%s)", me.username, me.id)

        ctx = await build_context(
            settings,
            AiogramGateway(bot),
            identity=BotIdentity(id=me.id, username=me.username),
        )

        dispatcher = build_dispatcher(ctx)

        try:
            await bot.delete_webhook(drop_pending_updates=False)
        except Exception:
            logger.warning(
                "could not delete webhook; polling may fail if a webhook is active",
                exc_info=True,
            )

        await bot.set_my_commands(COMMANDS)
        await ctx.scheduler.start()

        logger.info("polling started")

        await dispatcher.start_polling(
            bot,
            allowed_updates=["message", "callback_query", "channel_post"],
        )

    finally:
        if ctx is not None:
            await ctx.close()

        await bot.session.close()
        logger.info("shutdown complete")


def main() -> None:
    try:
        asyncio.run(run())
    except KeyboardInterrupt:
        pass


if __name__ == "__main__":
    main()
