# bot/management/commands/runbots.py
import asyncio
import logging
import signal
from django.core.management.base import BaseCommand
from bot.models import TelegramBot
from bot.bot_factory import build_application_for_bot

log = logging.getLogger(__name__)

class Command(BaseCommand):
    help = "Запуск ВСЕХ активных ботов (PTB 22.3) в одном процессе."

    def handle(self, *args, **options):
        logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s")
        asyncio.run(self._amain())

    async def _amain(self):
        bots = list(TelegramBot.objects.filter(is_active=True))
        if not bots:
            self.stderr.write(self.style.ERROR("Нет активных ботов (is_active=True)."))
            return

        apps = []
        try:
            # Инициализация и старт polling для каждого бота
            for tb in bots:
                app, allowed_updates = build_application_for_bot(tb)
                await app.initialize()
                await app.start()
                # в 22.x polling запускается через updater
                await app.updater.start_polling(allowed_updates=allowed_updates)
                apps.append(app)
                log.info("Bot started: %s (@%s)", tb.name, tb.username or "—")

            # Ожидание сигнала остановки
            stop_event = asyncio.Event()

            def _stop(*_):
                stop_event.set()

            loop = asyncio.get_running_loop()
            for sig in (signal.SIGINT, signal.SIGTERM):
                try:
                    loop.add_signal_handler(sig, _stop)
                except NotImplementedError:
                    # Windows
                    pass

            await stop_event.wait()

        finally:
            # Корректная остановка всех приложений
            for app in reversed(apps):
                try:
                    await app.updater.stop()
                    await app.stop()
                    await app.shutdown()
                except Exception:
                    log.exception("Shutdown error")
