from asyncio import sleep

import disnake
from disnake import Option, OptionType, Localized
from disnake.ext import tasks

from integral_lib.Comands import *
from integral_lib.DB_Worker import fill_bd, prepare_db, work_with_db
from integral_lib.Logger import logger


class Admin(commands.Cog, name='Admin'):
    def __init__(self, bot: commands.Bot):
        self.bot = bot  # a defining src as global var in class

    @commands.Cog.listener()  # this is a decorator for events/listeners
    async def on_ready(self):
        for g in self.bot.get_all_members():
            await prepare_db(g.guild.id)
        for g in self.bot.get_all_members():
            await fill_bd(g.name, g.id, g.bot, g.nick, g.guild.id)

        self.activity.start()
        logger.info(f'Cog {__name__.split(".")[1]} is ready!.')

    @tasks.loop(seconds=20)
    async def activity(self):
        await self.bot.change_presence(
            activity=disnake.Activity(
                name=f'at users: {str(len(self.bot.users))}',
                type=3
            )
        )
        await sleep(10)
        await self.bot.change_presence(
            activity=disnake.Activity(
                name=f'at servers: {str(len(self.bot.guilds))}',
                type=3
            )
        )

    @commands.Cog.listener()
    async def on_member_update(self, before: disnake.Member, after: disnake.Member):
        sql_update_query = f"""UPDATE "{after.guild.id}" set nick = ? where userid = ?"""
        data_tuple = (after.nick, before.id)
        await work_with_db(sql_update_query, data_tuple)

    @commands.Cog.listener()
    async def on_guild_join(self, guild):
        for g in guild.members:
            await fill_bd(g.name, g.id, g.bot, g.nick, guild.id)

    @commands.Cog.listener()
    async def on_member_join(self, member):
        await fill_bd(member.name, member.id, member.bot, member.nick, member.guild.id)

        bot_role = read_json(member.guild.id, 'bot_role')  # Get src role
        guest_role = read_json(member.guild.id, 'guest_role')  # Get guest role

        if bot_role or guest_role:
            if member.bot == 0:
                role = disnake.utils.get(member.guild.roles, id=guest_role)
            else:
                role = disnake.utils.get(member.guild.roles, id=bot_role)
            logger.info(f"Adding to {member} role {role}")
            await member.add_roles(role)

    @commands.slash_command(
        name="set_default_role",
        description=Localized("Set Default src role", key="DEF_ROLE"),
        options=[
            Option("role",
                   "Specify role",
                   OptionType.role,
                   required=True),
        ]
    )
    @commands.has_permissions(administrator=True)
    async def set_guest_role(self, inter: disnake.ApplicationCommandInteraction, role):
        await write_json(inter.guild.id, "guest_role", role.id)
        await inter.response.send_message(f"Set up src role to: `{role.name}`", ephemeral=True)

    @commands.command(name="set_prefix")
    @commands.has_permissions(administrator=True)
    async def command_set_prefix(self, ctx, prefix: str):
        await write_json(ctx.guild.id, "prefix", prefix)
        await ctx.reply(f"Prefix set to: `{prefix}`")

    @commands.guild_only()
    @commands.slash_command(
        name="set_prefix",
        description="Setting up src prefix",
        options=[
            Option("prefix",
                   "Specify prefix",
                   OptionType.string,
                   required=True),
        ]
    )
    @commands.has_permissions(administrator=True)
    async def slash_set_prefix(self, inter: disnake.ApplicationCommandInteraction, prefix: str):
        await write_json(inter.guild.id, "prefix", prefix)
        await inter.response.send_message(f"Prefix set to: `{prefix}`", ephemeral=True)

    @commands.guild_only()
    @commands.has_permissions(administrator=True)
    @commands.slash_command(
        name="set_trigger_role",
        description=Localized("Setting up role to trigger src", key="KEY_ROLE"),
        options=[
            Option("role",
                   Localized("Specify role", key="SETUP_ROLE"),
                   OptionType.role,
                   required=True),
        ]
    )
    async def set_trigger_role(self, inter: disnake.ApplicationCommandInteraction, role):
        await write_json(inter.guild.id, "tigger_role", role.id)
        await inter.response.send_message(f"Role set to: `{role.name}`", ephemeral=True)

    @commands.slash_command(
        name="set_bot_role",
        description=Localized("Set src role", key="BOT_ROLE"),
        options=[
            Option("role",
                   Localized("Specify role", key="SETUP_ROLE"),
                   OptionType.role,
                   required=True)
        ]
    )
    @commands.guild_only()
    @commands.has_permissions(administrator=True)
    async def set_bot_role(self, ctx, role):
        await write_json(ctx.guild.id,
                         "bot_role",
                         role.id)
        await ctx.send(f"Set up src role to: `{role.name}`", ephemeral=True)

    @set_bot_role.error
    @set_trigger_role.error
    @slash_set_prefix.error
    async def set_prefix_error(self, inter: disnake.ApplicationCommandInteraction, prefix):
        await inter.response.send_message("You don`t have permissions", ephemeral=True)
        logger.error(prefix)


def setup(bot):  # an extension must have a setup function
    bot.add_cog(Admin(bot))  # adding a cog
