import asyncio
import math
from datetime import datetime, timedelta

import discord
import pymysql
from discord.ext import commands


# password = open("../../../sqlPass.txt", 'r')

def get_con():
    return pymysql.connect(host='192.168.1.52',
                           port=5618,
                           user='Quentin',
                           password='kaPl0wskii',
                           db='mc',
                           charset='utf8mb4',
                           cursorclass=pymysql.cursors.DictCursor)


class McRoll(commands.Cog):
    def __init__(self, client):
        self.client = client
        self.currentPoll = None
        self.embedInfo = """Each server has a multiplier based on how long it has been sense that server has been rolled.
        When this poll is over all servers with 0 votes will be disregarded. 
        If there are 4 or more servers left the two with the lowest votes will be disregarded.
        Poll is rerun until there are only 2 servers, these two are the winners. Ties reroll the poll.
        You can only vote for one server per poll. """


    async def start_poll(self, ctx, choices):
        embed = discord.Embed(title="Poll", description=self.embedInfo, timestamp=datetime.now() + timedelta(hours=12))
        for choice in choices.items():
            choice = choice[1]
            embed.add_field(
                name=choice['serverName'] + ' ' + (str(self.client.get_emoji(int(choice['reaction'])))
                                                   if choice['getEmoji']
                                                   else bytes(choice['reaction'], "utf-8").decode("unicode_escape")),
                value="Multiplier : " + str(round(2 * math.log10(choice['lastActivated'] + 1) + 1, 2)) + '\n' +
                      "Last Rolled : " + str(choice['lastActivated'] * 2) + " weeks ago.")
        self.currentPoll = await ctx.channel.send(embed=embed)
        await ctx.channel.send("@everyone")
        for choice in choices.items():
            choice = choice[1]
            await self.currentPoll.add_reaction(self.client.get_emoji(int(choice['reaction']))
                                                if choice['getEmoji']
                                                else bytes(choice['reaction'], "utf-8").decode("unicode_escape"))
        await asyncio.sleep(43200)

        for reaction in self.currentPoll.reactions:
            async for user in reaction.users():
                serverIp = self.reaction_to_serverip(reaction)
                if user.id != 533427166193385494:
                    choices[serverIp]['votes'] = choices[serverIp]['votes'] + 1

                choices[serverIp]['score'] = choices[serverIp]['votes'] * round(
                    2 * math.log10(choices[serverIp]['lastActivated'] + 1) + 1, 2)

        for choice in list(choices):
            if choices[choice]['score'] <= 0:
                choices.pop(choice)
                continue

        if len(choices) >= 4:
            choices = self.pop_lowest(choices)
            choices = self.pop_lowest(choices)
        elif len(choices) == 3:
            choices = self.pop_lowest(choices)

        return choices


    def pop_lowest(self, choices):
        lowest = {'score': 10}
        pop = False
        for choice in list(choices):
            if choices[choice]['score'] < lowest['score']:
                lowest = choices[choice]
                pop = True
        if pop:
            choices.pop(lowest['serverIP'])
        return choices

    def reaction_to_serverip(self, reaction):
        con = get_con()
        escapedReaction = reaction.emoji.encode('unicode_escape').decode('utf-8')
        with con.cursor() as cursor:
            cursor.execute("SELECT serverIP FROM mc.server_list WHERE reaction=%s;", escapedReaction)
        serverIp = cursor.fetchone()
        con.close()
        return serverIp['serverIP']


    @commands.Cog.listener()
    async def on_reaction_add(self, reaction, user):
        reactedUsers = {}
        if reaction.message.id == self.currentPoll.id and user.id != 533427166193385494:
            for iReaction in reaction.message.reactions:
                async for iUser in iReaction.users():
                    if iUser.id != 533427166193385494:
                        if iUser.id not in reactedUsers:
                            reactedUsers[iUser.id] = False
                        if reactedUsers[iUser.id]:
                            await reaction.remove(user)
                            self.currentPoll = reaction.message
                            await user.send(
                                "You can only vote for one option, please remove your previous vote to change it.")
                            return
                        self.currentPoll = reaction.message
                        reactedUsers[iUser.id] = True


    @commands.command()
    async def mc_roll(self, ctx):
        if ctx.message.author.id != 305589587215122432:
            return

        con = get_con()
        with con.cursor() as cursor:
            cursor.execute("SELECT serverIP, serverName, lastActivated, reaction, getEmoji "
                           "FROM mc.server_list WHERE lastActivated is not null")
            choices = cursor.fetchall()
        con.close()

        dictChoices = {}
        for choice in choices:
            choice['score'] = 0
            choice['votes'] = 0
            dictChoices[choice['serverIP']] = choice

        dictChoices = await self.start_poll(ctx, dictChoices)

        while len(dictChoices) > 2:
            print(dictChoices)
            dictChoices = await self.start_poll(ctx, dictChoices)

        embed = discord.Embed(title="Winner", description="Congratulations")
        for item in list(dictChoices):
            winner = dictChoices[item]
            embed.add_field(
                name=winner['serverName'],
                value="Multiplier : " + str(round(2 * math.log10(winner['lastActivated'] + 1) + 1, 2)) + '\n' +
                      "Last Rolled : " + str(winner['lastActivated'] * 2) + " weeks ago." + '\n' +
                      "Votes : " + str(winner['votes']) + '\n' +
                      "Calculated Votes: " + str(winner['votes'] * round(2 * math.log10(winner['lastActivated'] + 1) + 1, 2))
            )

        await ctx.channel.send(embed=embed)
        await ctx.channel.send("@everyone")


def setup(client):
    client.add_cog(McRoll(client))
