import asyncio
import logging

from config import *
from start import router
from app.user import usermenu
from app.utils.command import set_bot_commands
from app.database.engine import init_db
from app.schedule_watcher import start_schedule_watcher
from app.daily_report import start_daily_report_task
from app.pending_sms_worker import start_pending_sms_worker
from app.admin_stats import start_admin_stats_task
from app.middleware.access import AccessMiddleware


dp.message.middleware(AccessMiddleware())
dp.callback_query.middleware(AccessMiddleware())

dp.include_routers(
    router,
    usermenu.router,
)


async def main():
    """Основная асинхронная функция запуска бота"""
    background_tasks: list[asyncio.Task] = []
    try:
        # Инициализируем базу (создаем таблицы / миграции колонок)
        await init_db()

        # Иначе апдейты уходят на webhook и long polling молчит
        await bot.delete_webhook(drop_pending_updates=False)

        me = await bot.get_me()
        logging.info("🚀 Бот запущен как @%s (id=%s)", me.username, me.id)
        if ALLOWED_USER_IDS:
            logging.info(
                "🔒 Whitelist активен: %s (+ admins %s)",
                sorted(ALLOWED_USER_IDS),
                sorted(ADMIN_USER_IDS) if ADMIN_USER_IDS else "—",
            )
        else:
            logging.info("🔓 Whitelist пуст — доступ открыт всем")

        background_tasks.append(start_schedule_watcher())
        background_tasks.append(start_daily_report_task())
        background_tasks.append(start_pending_sms_worker())
        background_tasks.append(start_admin_stats_task())
        logging.info(
            "⏰ Schedule watcher + daily report + pending SMS + admin stats started"
        )

        await dp.start_polling(bot)

    except Exception as e:
        logging.error(f"Ошибка запуска бота: {e}")
    finally:
        for t in background_tasks:
            if t is not None and not t.done():
                t.cancel()
                try:
                    await t
                except asyncio.CancelledError:
                    pass
        await bot.session.close()


# Запуск бота
if __name__ == "__main__":
    asyncio.run(main())
