# Path: dozer/cogs/levels.py
# class MemberXP(db.DatabaseTable):
#     """Database table mapping a guild and user to their XP and related values."""
#     __tablename__ = "levels_member_xp"
#     __uniques__ = "guild_id, user_id"
# 
#     @classmethod
#     async def initial_create(cls):
#         """Create the table in the database"""
#         async with db.Pool.acquire() as conn:
#             await conn.execute(f"""
#             CREATE TABLE {cls.__tablename__} (
#             guild_id bigint NOT NULL,
#             user_id bigint NOT NULL,
#             total_xp bigint NOT NULL,
#             total_messages int NOT NULL,
#             last_given_at timestamptz NOT NULL,
#             PRIMARY KEY (guild_id, user_id)
#             )""")
# 
#     def __init__(self, guild_id, user_id, total_xp, total_messages, last_given_at):
#         super().__init__()
#         self.guild_id = guild_id
#         self.user_id = user_id
#         self.total_xp = total_xp
#         self.total_messages = total_messages
#         self.last_given_at = last_given_at
# 
#     @classmethod
#     async def get_by(cls, **kwargs):
#         results = await super().get_by(**kwargs)
#         result_list = []
#         for result in results:
#             obj = MemberXP(guild_id=result.get("guild_id"), user_id=result.get("user_id"),
#                            total_xp=result.get("total_xp"), total_messages=result.get("total_messages"),
#                            last_given_at=result.get("last_given_at"))
#             result_list.append(obj)
#         return result_list
# 
# class GuildXPSettings(db.DatabaseTable):
#     """Database table containing per-guild settings related to XP gain."""
#     __tablename__ = "levels_guild_settings"
#     __uniques__ = "guild_id"
# 
#     @classmethod
#     async def initial_create(cls):
#         """Create the table in the database"""
#         async with db.Pool.acquire() as conn:
#             await conn.execute(f"""
#             CREATE TABLE {cls.__tablename__} (
#             guild_id bigint PRIMARY KEY NOT NULL,
#             xp_min int NOT NULL,
#             xp_max int NOT NULL,
#             xp_cooldown int NOT NULL,
#             entropy_value int NOT NULL,
#             lvl_up_msgs bigint NOT NULL,
#             enabled boolean NOT NULL
#             )""")
# 
#     def __init__(self, guild_id, xp_min, xp_max, xp_cooldown, entropy_value, enabled, lvl_up_msgs, keep_old_roles):
#         super().__init__()
#         self.guild_id = guild_id
#         self.xp_min = xp_min
#         self.xp_max = xp_max
#         self.xp_cooldown = xp_cooldown
#         self.entropy_value = entropy_value
#         self.enabled = enabled
#         self.lvl_up_msgs = lvl_up_msgs
#         self.keep_old_roles = keep_old_roles
# 
#     @classmethod
#     async def get_by(cls, **kwargs):
#         results = await super().get_by(**kwargs)
#         result_list = []
#         for result in results:
#             obj = GuildXPSettings(guild_id=result.get("guild_id"), xp_min=result.get("xp_min"), xp_max=result.get("xp_max"),
#                                   xp_cooldown=result.get("xp_cooldown"), entropy_value=result.get("entropy_value"), enabled=result.get("enabled"),
#                                   lvl_up_msgs=result.get("lvl_up_msgs"), keep_old_roles=result.get("keep_old_roles"))
#             result_list.append(obj)
#         return result_list
# 
#     async def version_1(self):
#         """DB migration v1"""
#         async with db.Pool.acquire() as conn:
#             await conn.execute(f"""
#             ALTER TABLE {self.__tablename__} ALTER COLUMN lvl_up_msgs DROP NOT NULL;
#             ALTER TABLE {self.__tablename__} ADD COLUMN IF NOT EXISTS keep_old_roles boolean NOT NULL default TRUE;
#             """)
# 
#     __versions__ = [version_1]


import math
import typing
import discord
import humanize
from datetime import timezone, datetime
from difflib import SequenceMatcher
from discord.ext.commands import cooldown, BucketType, guild_only
from discord_slash import cog_ext, SlashContext
from ._utils import *
from .levels import MemberXP, GuildXPSettings

class Info(Cog):
    """Commands for getting information about people and things on Discord."""

    @cog_ext.cog_slash(name="user", description="Returns user information")
    async def slash_member(self, ctx: SlashContext, member: discord.Member = None):
        """Users slash handler"""
        if member is None:
            member = ctx.guild.get_member(ctx.author.id)
        await self.member(ctx, member=member)

    @command(aliases=['user', 'memberinfo', 'userinfo'])
    @guild_only()
    @bot_has_permissions(embed_links=True)
    async def member(self, ctx, *, member: discord.Member = None):
        """Retrieve information about a member of the guild.
         If no arguments are passed, information about the author is used.
         **This command works without mentions.** Remove the '@' before your mention so you don't ping the person unnecessarily.
         You can pick a member by:
         - Username (`cooldude`)
         - Username and discriminator (`cooldude#1234`)
         - ID (`326749693969301506`)
         - Nickname - must be exact and is case-sensitive (`"Mr. Cool Dude III | Team 1234"`)
         - Mention (not recommended) (`@Mr Cool Dude III | Team 1234`)
         """
        if member is None:
            member = ctx.author
        footers = []

        levels_data = await MemberXP.get_by(guild_id=ctx.guild.id, user_id=member.id)

# Path: dozer/cogs/levels.py
# class MemberXP(db.DatabaseTable):
#     """Database table mapping a guild and user to their XP and related values."""
#     __tablename__ = "levels_member_xp"
#     __uniques__ = "guild_id, user_id"
# 
#     @classmethod
#     async def initial_create(cls):
#         """Create the table in the database"""
#         async with db.Pool.acquire() as conn:
#             await conn.execute(f"""
#             CREATE TABLE {cls.__tablename__} (
#             guild_id bigint NOT NULL,
#             user_id bigint NOT NULL,
#             total_xp bigint NOT NULL,
#             total_messages int NOT NULL,
#             last_given_at timestamptz NOT NULL,
#             PRIMARY KEY (guild_id, user_id)
#             )""")
# 
#     def __init__(self, guild_id, user_id, total_xp, total_messages, last_given_at):
#         super().__init__()
#         self.guild_id = guild_id
#         self.user_id = user_id
#         self.total_xp = total_xp
#         self.total_messages = total_messages
#         self.last_given_at = last_given_at
# 
#     @classmethod
#     async def get_by(cls, **kwargs):
#         results = await super().get_by(**kwargs)
#         result_list = []
#         for result in results:
#             obj = MemberXP(guild_id=result.get("guild_id"), user_id=result.get("user_id"),
#                            total_xp=result.get("total_xp"), total_messages=result.get("total_messages"),
#                            last_given_at=result.get("last_given_at"))
#             result_list.append(obj)
#         return result_list
# 
# class GuildXPSettings(db.DatabaseTable):
#     """Database table containing per-guild settings related to XP gain."""
#     __tablename__ = "levels_guild_settings"
#     __uniques__ = "guild_id"
# 
#     @classmethod
#     async def initial_create(cls):
#         """Create the table in the database"""
#         async with db.Pool.acquire() as conn:
#             await conn.execute(f"""
#             CREATE TABLE {cls.__tablename__} (
#             guild_id bigint PRIMARY KEY NOT NULL,
#             xp_min int NOT NULL,
#             xp_max int NOT NULL,
#             xp_cooldown int NOT NULL,
#             entropy_value int NOT NULL,
#             lvl_up_msgs bigint NOT NULL,
#             enabled boolean NOT NULL
#             )""")
# 
#     def __init__(self, guild_id, xp_min, xp_max, xp_cooldown, entropy_value, enabled, lvl_up_msgs, keep_old_roles):
#         super().__init__()
#         self.guild_id = guild_id
#         self.xp_min = xp_min
#         self.xp_max = xp_max
#         self.xp_cooldown = xp_cooldown
#         self.entropy_value = entropy_value
#         self.enabled = enabled
#         self.lvl_up_msgs = lvl_up_msgs
#         self.keep_old_roles = keep_old_roles
# 
#     @classmethod
#     async def get_by(cls, **kwargs):
#         results = await super().get_by(**kwargs)
#         result_list = []
#         for result in results:
#             obj = GuildXPSettings(guild_id=result.get("guild_id"), xp_min=result.get("xp_min"), xp_max=result.get("xp_max"),
#                                   xp_cooldown=result.get("xp_cooldown"), entropy_value=result.get("entropy_value"), enabled=result.get("enabled"),
#                                   lvl_up_msgs=result.get("lvl_up_msgs"), keep_old_roles=result.get("keep_old_roles"))
#             result_list.append(obj)
#         return result_list
# 
#     async def version_1(self):
#         """DB migration v1"""
#         async with db.Pool.acquire() as conn:
#             await conn.execute(f"""
#             ALTER TABLE {self.__tablename__} ALTER COLUMN lvl_up_msgs DROP NOT NULL;
#             ALTER TABLE {self.__tablename__} ADD COLUMN IF NOT EXISTS keep_old_roles boolean NOT NULL default TRUE;
#             """)
# 
#     __versions__ = [version_1]


# Path: dozer/cogs/info.py
import math
import typing
import discord
import humanize
from datetime import timezone, datetime
from difflib import SequenceMatcher
from discord.ext.commands import cooldown, BucketType, guild_only
from discord_slash import cog_ext, SlashContext
from ._utils import *
from .levels import MemberXP, GuildXPSettings


class Info(Cog):
    """Commands for getting information about people and things on Discord."""

    @cog_ext.cog_slash(name="user", description="Returns user information")
    async def slash_member(self, ctx: SlashContext, member: discord.Member = None):
        """Users slash handler"""
        if member is None:
            member = ctx.guild.get_member(ctx.author.id)
        await self.member(ctx, member=member)

    @command(aliases=['user', 'memberinfo', 'userinfo'])
    @guild_only()
    @bot_has_permissions(embed_links=True)
    async def member(self, ctx, *, member: discord.Member = None):
        """Retrieve information about a member of the guild.
         If no arguments are passed, information about the author is used.
         **This command works without mentions.** Remove the '@' before your mention so you don't ping the person unnecessarily.
         You can pick a member by:
         - Username (`cooldude`)
         - Username and discriminator (`cooldude#1234`)
         - ID (`326749693969301506`)
         - Nickname - must be exact and is case-sensitive (`"Mr. Cool Dude III | Team 1234"`)
         - Mention (not recommended) (`@Mr Cool Dude III | Team 1234`)
         """
        if member is None:
            member = ctx.author
        footers = []

        levels_data = await MemberXP.get_by(guild_id=ctx.guild.id, user_id=member.id)

        levels_settings = await GuildXPSettings.get_by(guild_id=ctx.guild.id)