"""
Точка входа PrimoGuard Bot
"""
from asyncio import run

from configs import settings
from bot import bot, dp, BotInfo, WebhookManager, setup_middlewares, router
from database import get_manager
from middleware.loggers import logger

__all__ = ("main",)


async def setup_services(setup_webhook: bool = True) -> str:
    """
    Инициализация всех сервисов: БД и бот.

    Args:
        setup_webhook: Устанавливать ли webhook в BotInfo.setup()

    Returns:
        str: Username бота
    """
    # База данных
    manager = get_manager()
    await manager.init()

    stats = await manager.get_stats()
    logger.info(
        f"📊 БД инициализирована: {stats.get('total_banwords', 0)} банвордов",
        log_type="DATABASE"
    )

    # Бот: получение информации (БЕЗ webhook)
    await BotInfo.setup(bots=bot, setup_webhook=setup_webhook)

    # ВАЖНО: Регистрируем middleware и роутеры ДО установки webhook
    setup_middlewares(
        dp=dp,
        bot=bot,
        enable_spam_check=settings.ANTI_SPAM,
        channel_ids=[],
    )

    # Подключение маршрутов
    dp.include_router(router)

    logger.info("✓ Все handlers и middleware зарегистрированы", log_type="STARTUP")

    return BotInfo.username


async def on_startup(app) -> None:
    """Выполняется при запуске webhook-сервера."""
    # 1. Инициализируем всё БЕЗ webhook
    username = await setup_services(setup_webhook=False)

    # 2. ТЕПЕРЬ устанавливаем webhook (когда всё готово)
    webhook = WebhookManager(bot, dp)

    if settings.WEBHOOK_URL:
        success = await webhook.setup(
            webhook_url=settings.WEBHOOK_URL,
            secret_token=settings.SECRET_TOKEN,
            drop_pending_updates=True
        )

        if success:
            logger.success(
                f"✅ Бот @{username} запущен в режиме Webhook",
                log_type="STARTUP"
            )
        else:
            logger.error(
                "❌ Не удалось установить webhook, но сервер запущен",
                log_type="STARTUP"
            )
    else:
        logger.warning(
            "⚠️ WEBHOOK_URL не указан",
            log_type="STARTUP"
        )


async def on_shutdown(app) -> None:
    """Очистка ресурсов при остановке сервера."""
    logger.info("👋 Остановка бота...", log_type="SHUTDOWN")

    try:
        await get_manager().close()
        await bot.session.close()
    except Exception as e:
        logger.error(f"Ошибка при закрытии: {e}", log_type="SHUTDOWN")

    logger.success("✅ Бот остановлен", log_type="SHUTDOWN")


def start_webhook() -> None:
    """Запуск в режиме Webhook (синхронный)."""
    logger.setup()

    webhook = WebhookManager(bot, dp)

    # ВАЖНО: Конфигурируем webhook ПЕРЕД on_startup
    webhook.configure()

    # Добавляем startup/shutdown handlers
    webhook.app.on_startup.append(on_startup)
    webhook.app.on_shutdown.append(on_shutdown)

    # Запускаем webhook сервер
    logger.info("🌐 Запуск Webhook сервера...", log_type="MAIN")
    webhook.run()


async def start_polling() -> None:
    """Запуск в режиме Polling (асинхронный)."""
    logger.setup()

    try:
        username = await setup_services(setup_webhook=False)

        # Удаляем webhook для polling режима
        webhook = WebhookManager(bot, dp)
        await webhook.delete(drop_pending_updates=True)

        logger.success(
            f"✅ Бот @{username} запущен в режиме Polling",
            log_type="STARTUP"
        )

        # Запускаем polling
        await dp.start_polling(bot, drop_pending_updates=True)

    except Exception as e:
        logger.critical(
            f"🔥 Критическая ошибка: {e}",
            log_type="MAIN"
        )
        raise

    finally:
        try:
            await bot.session.close()
            await get_manager().close()
        except:
            pass


def main() -> None:
    """Входная точка проекта."""
    try:
        if settings.WEBHOOK:
            # ========== WEBHOOK РЕЖИМ ==========
            start_webhook()
        else:
            # ========== POLLING РЕЖИМ ==========
            run(start_polling())

    except KeyboardInterrupt:
        logger.info("⚠️ Остановка по сигналу Ctrl+C", log_type="MAIN")

    except Exception as e:
        logger.critical(
            f"🔥 Критическая ошибка при запуске: {e}",
            log_type="MAIN"
        )
        raise


if __name__ == "__main__":
    main()
