import logging

import discord
from redbot.core import Config, commands
from redbot.core.bot import Red

log = logging.getLogger("red.historian.reactioner")

class ReactionDeleter(commands.Cog):
    """Delete an message which has x amount of reactions in the configured channels."""

    def __init__(self, bot: Red):
        self.bot = bot
        self.config = Config.get_conf(self, identifier=0x93A3AC10042001E, force_registration=True)
        default_guild = {
            "channels": [],
            "emoji": None,
            "limit": None,
            "log_channel": None,
        }
        self.config.register_guild(**default_guild)

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, payload):

        if payload.member.bot:
            return

        guild = self.bot.get_guild(payload.guild_id)

        if payload.channel_id not in await self.config.guild(guild).channels():
            return

        emoji: discord.PartialEmoji = payload.emoji

        if emoji.id != await self.config.guild(guild).emoji():
            return

        channel = self.bot.get_channel(payload.channel_id)

        message = await channel.fetch_message(payload.message_id)

        if message.author.bot:
            return
        
        reacted_emojis = [i for i in message.reactions if i.custom_emoji]

        if len(reacted_emojis) == 0:
            return

        for x in reacted_emojis:
            if x.emoji.id == await self.config.guild(guild).emoji():
                if x.count != await self.config.guild(guild).limit():
                    return
                else:
                    log_channel = await self.config.guild(guild).log_channel()
                    if log_channel != None:
                        try:
                            await guild.get_channel(log_channel).send(
                                embed=self._format_message(message)
                            )
                        except (discord.HTTPException, discord.Forbidden):
                            pass
                    try:
                        await message.delete()
                    except (discord.HTTPException, discord.Forbidden):
                        log.info("Cannot delete messages. Bot probably do not have perms or something. Let the author known.")
                        

    def _format_message(self, message: discord.Message):
        """Format an message to an embed."""
        embed = discord.Embed()
        embed.color = discord.Color.red()
        embed.timestamp = message.created_at
        embed.description = "Message deleted by reaction deletion."
        embed.set_author(name=str(message.author), icon_url=message.author.avatar_url)
        embed.add_field(name="**Deleted Message:**", value=message.content[:5000])
        embed.set_footer(text=f"Channel: {message.channel.name} | Message Sent")

        return embed

    @commands.group()
    @commands.has_permissions(manage_guild=True)
    async def reactionset(self, ctx: commands.Context):
        """Commands to setup the reaction deleter."""

    @reactionset.command(name="add")
    async def _channels_add(self, ctx: commands.Context, channel: discord.TextChannel):
        """Add a channel to the tracked channels."""

        async with self.config.guild(ctx.guild).channels() as c:
            if channel.id in c:
                return await ctx.send(f"{channel.mention} is already being tracked for reactions.")
            c.append(channel.id)

        await ctx.send(f"{channel.mention} add to the tracking list.")

    @reactionset.command(name="emoji")
    async def _emoji(self, ctx: commands.Context, emoji: discord.Emoji):
        """Set the emoji to check for reactions."""

        await self.config.guild(ctx.guild).emoji.set(emoji.id)
        await ctx.send(f"{emoji} will now be checked on reactions.")

    @reactionset.command(name="limit")
    async def _count(self, ctx: commands.Context, count: int):
        """Set the amount of reactions to check for."""

        await self.config.guild(ctx.guild).limit.set(count)
        await ctx.send(
            f"I will now delete messages which have {count} reactions of {discord.utils.get(self.bot.emojis, id=await self.config.guild(ctx.guild).emoji())}"
        )

    @reactionset.command(name="log-channel")
    async def _reaction_log(self, ctx: commands.Context, channel: discord.TextChannel):
        """Set the log channel for message deletes."""

        await self.config.guild(ctx.guild).log_channel.set(channel.id)
        await ctx.send(f"{channel.mention} will now be used for logging reaction deletes.")

    @reactionset.command(name="remove")
    async def _channels_remove(self, ctx: commands.Context, channel: discord.TextChannel):
        """Remove a channel from the tracked channels."""

        async with self.config.guild(ctx.guild).channels() as c:
            if channel.id not in c:
                return await ctx.send(
                    f"{channel.mention} is already not being tracked for reactions."
                )
            c.remove(channel.id)

        await ctx.send(f"{channel.mention} removed from the tracking list.")

    @reactionset.command(name="showsettings")
    async def _show_settings(self, ctx: commands.Context):
        """Show the settings of this cog."""

        msg = "**__Reaction Deleter Settings__**\n"
        msg += "**Channels:** {}\n".format(
            ",".join(
                [
                    ctx.guild.get_channel(i).name
                    for i in await self.config.guild(ctx.guild).channels()
                ]
            )
        )
        msg += "**Emoji:** {}\n".format(
            discord.utils.get(self.bot.emojis, id=await self.config.guild(ctx.guild).emoji())
        )
        msg += "**Limit:** {}".format(await self.config.guild(ctx.guild).limit())
        await ctx.send(msg)