# Aiogram
from aiogram.types.bot_command_scope_all_private_chats import (
    BotCommandScopeAllPrivateChats,
)
from aiogram.exceptions import TelegramNetworkError

# Bot
from create_bot import bot, dp, start_command, orm

# Entry
from handlers.start import start_router
from handlers.admin.main import admin_main_router

# Client handlers
from handlers.client.main import client_router

# Admin handlers
from handlers.admin.list_of_users import list_of_users_router
from handlers.admin.statistic import admin_statistic_router
from handlers.admin.management import admin_management_router
from handlers.admin.mailer import admin_mailer_router
from handlers.admin.settings import admin_settings_router
from handlers.admin.blacklist import admin_blacklist_router

# middlewares
from middlewares.users_control import *
from middlewares.album import AlbumMiddleware

# Another
import asyncio
import logging
from decouple import config
from uvloop import run


logger = logging.getLogger(__name__)


async def safe_set_my_commands(retries: int = 3, delay_seconds: int = 5) -> None:
    for attempt in range(1, retries + 1):
        try:
            await bot.set_my_commands(
                start_command,
                scope=BotCommandScopeAllPrivateChats(),
                request_timeout=120,
            )
            return
        except TelegramNetworkError as exc:
            if attempt == retries:
                logger.warning(
                    "Could not set bot commands after %s attempts: %s",
                    retries,
                    exc,
                )
                return
            logger.warning(
                "Telegram API timeout while setting commands, retry %s/%s in %ss",
                attempt,
                retries,
                delay_seconds,
            )
            await asyncio.sleep(delay_seconds)


async def main():
    try:
        await orm.init_schema()
        await safe_set_my_commands()
        await orm.create_admin(int(config("BASE_ADMIN")), "base_admin", "base_admin")

        dp.message.middleware(BlacklistMiddleware())
        dp.callback_query.middleware(BlacklistMiddleware())
        dp.message.middleware(AntiFloodMiddleware())
        dp.message.middleware(AlbumMiddleware())

        # ENTRY POINTS
        dp.include_routers(start_router, admin_main_router)

        # CLIENT
        dp.include_router(client_router)

        # ADMIN
        dp.include_routers(
            list_of_users_router,
            admin_statistic_router,
            admin_management_router,
            admin_mailer_router,
            admin_settings_router,
            admin_blacklist_router,
        )

        # await bot.delete_webhook(drop_pending_updates = True)
        await dp.start_polling(bot)
    finally:
        await bot.session.close()
        await orm.close()


if __name__ == "__main__":
    run(main())
