# RT Ext - Useful Util
# 注意：普通のエクステンションとは違います。

import asyncio
from json import dumps
from time import time

import discord
from aiofile import async_open
from discord.ext import commands, tasks


class RtUtil(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.data = {
            "list_embed": {}
        }

        self.ARROW_EMOJI = ["◀️", "▶️"]

        self.now = time()
        self.save_queue = []

        self.list_embed_timeout_loop.start()

    def list_embed(self, member_id: int, embeds: list[discord.Embed],
                   timeout: int = 60, anyone: bool = False
                   ) -> list[discord.Embed, list[str]]:
        self.data["list_embed"][member_id] = {
            "embeds": [embed.to_dict() for embed in embeds],
            "timeout": self.now + timeout,
            "anyone": anyone
        }
        return embeds[0], self.ARROW_EMOJI

    @tasks.loop(seconds=5)
    async def list_embed_timeout_loop(self):
        for user_id in self.data["list_embed"]:
            if self.now > self.data["list_embed"][user_id]["timeout"]:
                del self.data["list_embed"][user_id]

    async def list_embed_reaction_task(self, reaction, user):
        # === list embed === #
        if (not reaction.message.embeds
                or str(reaction.emoji) not in self.ARROW_EMOJI
                or reaction.message.author.id != self.bot.user.id
                or user.id not in self.data["list_embed"]):
            return

        embed = reaction.message.embeds[0]
        now_embed = embed.to_dict()
        for user_id in self.data["list_embed"]:
            if (now_embed in self.data["list_embed"][user.id]["embeds"]
                    and user_id == user.id):
                data = self.data["list_embed"][user.id]
                now = data["embeds"].index(now_embed)

                next_page = 0
                if str(reaction.emoji) == self.ARROW_EMOJI[0]:
                    next_page = now - 1
                elif str(reaction.emoji) == self.ARROW_EMOJI[1]:
                    next_page = now + 1
                if len(data["embeds"]) != next_page and now != 0:
                    embed = data["embeds"][next_page]
                    await reaction.message.edit(embed=embed)

                break
        try:
            await reaction.message.remove_reaction(str(reaction.emoji), user)
        except Exception:
            pass

    @commands.Cog.listener()
    async def on_reaction_add(self, reaction, user):
        await self.list_embed_reaction_task(reaction, user)

    def unload_cog(self):
        self.list_embed_timeout_loop.cancel()


# Webhook Sender
async def send(channel, author, content=None, embeds=None,
               files=None, wait=False, name='RT-Tool'):
    wb = discord.utils.get(await channel.webhooks(), name=name)
    wb = wb if wb else await channel.create_webhook(name=name)
    return await wb.send(wait=wait, username=author.name,
                         avatar_url=author.avatar_url, content=content,
                         embeds=embeds, files=files)


async def not_author_send(channel, author_name, icon_url, content=None,
                          embeds=None, files=None, wait=False, name='RT-Tool'):
    wb = discord.utils.get(await channel.webhooks(), name=name)
    wb = wb if wb else await channel.create_webhook(name=name)
    return await wb.send(wait=wait, username=author_name, avatar_url=icon_url,
                         content=content, embeds=embeds, files=files)


# easy_embed
def easy_embed(content, color=discord.Embed.Empty):
    es = ">>"
    spl = content.splitlines()
    title = spl[0][len(es):]
    desc, fields = [], {}
    footer = None if ';;' not in spl[-1] else spl[-1][2:]
    if footer:
        spl.pop(-1)
    spl.pop(0)
    f = None
    for c in spl:
        if c == "":
            continue
        if c[0] == '<':
            f = c[1:] if '!' != c[1] else c[2:]
            fields[f] = {'i': True if '!' != c[1] else False, 'c': []}
            continue
        if f:
            fields[f]['c'].append(c)
            continue
        desc.append(c)
    e = discord.Embed(
        title=title,
        description='\n'.join(desc),
        color=color
    )
    for f in fields.keys():
        e.add_field(
            name=f,
            value='\n'.join(fields[f]['c']),
            inline=fields[f]['i']
        )
    if footer:
        e.set_footer(text=footer)
    return e


# Role TOOL
def check_int(v):
    try:
        int(v)
    except BaseException:
        return False
    else:
        return True


def has_roles(member, roles):
    return any(bool(discord.utils.get(
        member.roles, id=role.id)) for role in roles)


def role2obj(guild, arg):
    roles_raw, roles = arg.split(','), []
    for role in roles_raw:
        if '@' in role:
            roles.append(guild.get_role(int(role[3:-1])))
        elif check_int(role):
            roles.append(guild.get_role(int(role)))
        else:
            roles.append(discord.utils.get(guild.roles, name=role))
    return roles


class Roler(discord.ext.commands.Converter):
    async def convert(self, ctx, arg):
        return role2obj(ctx.guild, arg)


def similer(b, a, m):
    return any(a[i:i + m] in b for i in range(len(a) - m))


def setup(bot):
    return RtUtil(bot)

# RT Ext - Useful Util
# 注意：普通のエクステンションとは違います。

import asyncio
from json import dumps
from time import time

import discord
from aiofile import async_open
from discord.ext import commands, tasks


class RtUtil(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.data = {
            "list_embed": {}
        }

        self.ARROW_EMOJI = ["◀️", "▶️"]

        self.now = time()
        self.save_queue = []

        self.list_embed_timeout_loop.start()

    def list_embed(self, member_id: int, embeds: list[discord.Embed],
                   timeout: int = 60, anyone: bool = False
                   ) -> list[discord.Embed, list[str]]:
        self.data["list_embed"][member_id] = {
            "embeds": [embed.to_dict() for embed in embeds],
            "timeout": self.now + timeout,
            "anyone": anyone
        }
        return embeds[0], self.ARROW_EMOJI

    @tasks.loop(seconds=5)
    async def list_embed_timeout_loop(self):
        for user_id in self.data["list_embed"]:
            if self.now > self.data["list_embed"][user_id]["timeout"]:
                del self.data["list_embed"][user_id]

    async def list_embed_reaction_task(self, reaction, user):
        # === list embed === #
        if (not reaction.message.embeds
                or str(reaction.emoji) not in self.ARROW_EMOJI
                or reaction.message.author.id != self.bot.user.id
                or user.id not in self.data["list_embed"]):
            return

        embed = reaction.message.embeds[0]
        now_embed = embed.to_dict()
        for user_id in self.data["list_embed"]:
            if (now_embed in self.data["list_embed"][user.id]["embeds"]
                    and user_id == user.id):
                data = self.data["list_embed"][user.id]
                now = data["embeds"].index(now_embed)

                next_page = 0
                if str(reaction.emoji) == self.ARROW_EMOJI[0]:
                    next_page = now - 1
                elif str(reaction.emoji) == self.ARROW_EMOJI[1]:
                    next_page = now + 1
                if len(data["embeds"]) != next_page and now != 0:
                    embed = data["embeds"][next_page]
                    await reaction.message.edit(embed=embed)

                break
        try:
            await reaction.message.remove_reaction(str(reaction.emoji), user)
        except Exception:
            pass

    @commands.Cog.listener()
    async def on_reaction_add(self, reaction, user):
        await self.list_embed_reaction_task(reaction, user)

    def unload_cog(self):
        self.list_embed_timeout_loop.cancel()


# Webhook Sender
async def send(channel, author, content=None, embeds=None,
               files=None, wait=False, name='RT-Tool'):
    wb = discord.utils.get(await channel.webhooks(), name=name)
    wb = wb if wb else await channel.create_webhook(name=name)
    return await wb.send(wait=wait, username=author.name,
                         avatar_url=author.avatar_url, content=content,
                         embeds=embeds, files=files)


async def not_author_send(channel, author_name, icon_url, content=None,
                          embeds=None, files=None, wait=False, name='RT-Tool'):
    wb = discord.utils.get(await channel.webhooks(), name=name)
    wb = wb if wb else await channel.create_webhook(name=name)
    return await wb.send(wait=wait, username=author_name, avatar_url=icon_url,
                         content=content, embeds=embeds, files=files)


# easy_embed
def easy_embed(content, color=discord.Embed.Empty):
    es = ">>"
    spl = content.splitlines()
    title = spl[0][len(es):]
    desc, fields = [], {}
    footer = None if ';;' not in spl[-1] else spl[-1][2:]
    if footer:
        spl.pop(-1)
    spl.pop(0)
    f = None
    for c in spl:
        if c == "":
            continue
        if c[0] == '<':
            f = c[1:] if '!' != c[1] else c[2:]
            fields[f] = {'i': True if '!' != c[1] else False, 'c': []}
            continue
        if f:
            fields[f]['c'].append(c)
            continue
        desc.append(c)
    e = discord.Embed(
        title=title,
        description='\n'.join(desc),
        color=color
    )
    for f in fields.keys():
        e.add_field(
            name=f,
            value='\n'.join(fields[f]['c']),
            inline=fields[f]['i']
        )
    if footer:
        e.set_footer(text=footer)
    return e


# Role TOOL
def check_int(v):
    try:
        int(v)
    except BaseException:
        return False
    else:
        return True


def has_roles(member, roles):
    return any(bool(discord.utils.get(
        member.roles, id=role.id)) for role in roles)


def role2obj(guild, arg):
    roles_raw, roles = arg.split(','), []
    for role in roles_raw:
        if '@' in role:
            roles.append(guild.get_role(int(role[3:-1])))
        elif check_int(role):
            roles.append(guild.get_role(int(role)))
        else:
            roles.append(discord.utils.get(guild.roles, name=role))
    return roles


class Roler(discord.ext.commands.Converter):
    async def convert(self, ctx, arg):
        return role2obj(ctx.guild, arg)


def similer(b, a, m):
    return any(a[i:i + m] in b for i in range(len(a) - m))


def setup(bot):
    return RtUtil(bot)

# RT Ext - Useful Util # 注意：普通のエクステンションとは違います。 # === list embed === # # Webhook Sender # easy_embed # Role TOOL