<gh_stars>1-10
import datetime
import discord
import humanize
import os
import platform
import psutil
import time
from discord import Color
from discord.ext import commands
from sqlalchemy import and_, func
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.future import select
from urllib.parse import urlparse

from ..core.logging import getlogger
from ..core.models import Server, Posts, Users, Feedback, General, Tokens
from ..core.tokens import award_token, consume_token, rank_updater
from ..utils.checks import in_database, is_feedback_channel
from ..utils.embeds import EmbedProfile
from ..utils.helpers import survey

logger = getlogger(__name__)

class Profiles(commands.Cog, description=f"User and server "
                       , name = "profiles"):
    def __init__(self, bot):
        self.bot = bot
    async def cog_check(self, ctx):
        return True  # Whatever check you want to do

    @in_database()
    @commands.command(
        description=f"Displays user information"
        , brief="User information"
    )
    async def userinfo(self, ctx, user=None):

        if user is None:
            userinfo = ctx.message.author
        else:
            userinfo = ctx.guild.get_member_named(user)

        if userinfo is None:
            raise commands.UserInputError(f"Invalid username { user }")

        expiration = datetime.datetime.today() - datetime.timedelta(hours=24)

        async with ctx.bot.engine.connect() as conn:
            stmt = (
                select(Users
                       , func.count(Tokens.id.distinct()).label("tokens_c")
                       , func.count(Posts.id.distinct()).label("posts_c")
                       , func.count(Feedback.id.distinct()).label("feedback_c")
                       , func.avg(Feedback.rating).label("avg_rating")
                       , Server.ranks.label("user_ranks")
                       )
                    .outerjoin(Tokens
                          , and_(Users.uid==Tokens.owner
                                 , Tokens.available == True
                                 , Tokens.created_at >= expiration
                                 , Tokens.guild == ctx.guild.id)
                          )
                    .outerjoin(Posts
                        , and_(Posts.userid == Users.uid
                               , Posts.guild == ctx.guild.id
                              )
                         )
                    .outerjoin(Feedback
                               , and_(Feedback.author_id == Users.uid
                                      , Feedback.guild == ctx.guild.id
                                      )
                               )
                    .outerjoin(Server
                               , Server.guild == ctx.guild.id)
                    .group_by(Server.ranks)
                    .where(Users.guild == ctx.guild.id
                           , Users.uid == userinfo.id
                           )
                    .group_by(Users.id)
            )
            result = await conn.execute(stmt)
            userdata = result.fetchone()._asdict()
        rankemoji = next(x for x in userdata['user_ranks'] if x['rank'].lower() == userdata['rank'].lower() )['emoji']
        avg_rating = round((userdata['avg_rating'] * 100) if userdata['avg_rating'] is not None else 0,2)
        embed_user_info = EmbedProfile(title=f"👤 User information for **{userinfo.name} \n { rankemoji }{ userdata['rank'] } ** "
                                  , description=f""
                                  , color=Color.red())
        embed_user_info.set_thumbnail(url=userinfo.avatar_url)
        embed_user_info.add_field(name="📣 Posts", value=f"> { userdata['posts_c'] }",inline=True)
        embed_user_info.add_field(name="\u200b", value=f"\u200b", inline=True)
        embed_user_info.add_field(name="🗣 Feedbacks", value=f"> { userdata['feedback_c'] }",inline=True)


        embed_user_info.add_field(name="🧆 Tokens", value=f"> { userdata['tokens_c'] }",inline=True)
        embed_user_info.add_field(name="\u200b", value=f"\u200b", inline=True)
        embed_user_info.add_field(name="⚖ Rating", value=f"> { avg_rating }%",inline=True)

        await ctx.send(embed=embed_user_info)

    @in_database()
    @commands.command(
        description=f"Displays server information"
        , brief="Server information"
    )

    async def serverinfo(self, ctx):
        embed_server_info = EmbedProfile(title=f"👥 Server information for **{ctx.guild}** ")
        embed_server_info.set_thumbnail(url=ctx.guild.icon_url)
        embed_server_info.add_field(name="💎 Shard №", value=f"> {ctx.guild.shard_id}",inline=True)
        embed_server_info.add_field(name="🗣 Active Users", value=f"> 3",inline=True)
        embed_server_info.add_field(name="\u200b", value=f"\u200b", inline=True)

        embed_server_info.add_field(name="🧆 Active Tokens", value=f"> 3",inline=True)
        embed_server_info.add_field(name="💱 Feedback channel", value=f"> $feedback",inline=True)
        embed_server_info.add_field(name="\u200b", value=f"\u200b", inline=True)
        await ctx.send(embed=embed_server_info)
def setup(bot):
    bot.add_cog(Profiles(bot))