import logging

import discord
from discord.ext import commands
from django.core.management.base import BaseCommand, CommandError

from opcalendar.app_settings import OPCALENDAR_DISCORD_BOT_TOKEN
from opcalendar.cogs.event_channel import EventChannelSync
from opcalendar.cogs.ops import Ops

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    help = (
        "Runs opcalendar's standalone Discord bot, which keeps a pinned "
        "summary of upcoming events synced in Discord event channels and "
        "provides the /signup and /ops slash commands. "
        "Run this as its own long-lived process (e.g. a supervisor program)."
    )

    def handle(self, *args, **options):
        if not OPCALENDAR_DISCORD_BOT_TOKEN:
            raise CommandError(
                "OPCALENDAR_DISCORD_BOT_TOKEN is not set. Add it to your "
                "local.py before running this command."
            )

        intents = discord.Intents.default()
        intents.reactions = True

        bot = commands.Bot(command_prefix="!opcalendar ", intents=intents)

        @bot.event
        async def on_ready():
            logger.info("opcalendar event channel bot logged in as %s", bot.user)
            self.stdout.write(
                self.style.SUCCESS(f"Logged in as {bot.user} — bot is now running")
            )

        async def runner():
            bot.add_cog(EventChannelSync(bot))
            bot.add_cog(Ops(bot))
            await bot.start(OPCALENDAR_DISCORD_BOT_TOKEN)

        try:
            bot.loop.run_until_complete(runner())
        except KeyboardInterrupt:
            pass
        finally:
            if not bot.is_closed():
                bot.loop.run_until_complete(bot.close())
