# -*- coding: utf-8 -*-

import discord
import asyncio
import pickle
import codecs
import string
import json
import random

from funcs import *

commandPrefix = "!"

# Blackjack shuffle variables
blackjackMinCards = 50
blackjackDecks = 4

# Variable for reacting to messages
meanWords = ["stupid", "bitch", "fuck", "dumb", "idiot"]

async def parseCommands(message,content):
    # Sends the contents of a help file, as specified by the message.
    if content.startswith("help"):
        if content == "help" or content == "help ":
            with codecs.open("resources/help/help.txt",encoding="utf-8") as f:
                text = f.read()
            em = discord.Embed(title = "Help", description = text,colour = 0x59f442)
            await message.channel.send(embed = em)
        else:
            command = content.replace(" ","-")
            logThis("Looking for "+command+".txt")
            try:
                with codecs.open("resources/help/"+command+".txt",encoding="utf-8") as f:
                    text = f.read()
                em = discord.Embed(title = command.replace("help-","").capitalize(), description = text,colour = 0x59f442)
                await message.channel.send(embed = em)
            except:
                await message.channel.send("Couldn't find help for that command")
    
    # Logs whatever you write in the message
    if content.startswith("log "):
        logThis(content.replace("log ",""))

    # Stops the bot
    elif content.startswith("stop"):
        if message.author.display_name == "Nikolaj":
            await message.channel.send("Logging out...")

            with open("resources/games/games.json","r") as f:
                data = json.load(f)
            
            data["trivia questions"] = {}
            data["blackjack games"] = {}
            data["4 in a row games"] = {}
            
            with open("resources/games/games.json","w") as f:
                json.dump(data,f,indent=4)

            await client.logout()
        else:
            logThis(message.author.display_name+" tried to run stop me!")
            await message.channel.send("I don't think I will, "+message.author.display_name)

    # Does a hello with the helloFunc function from funcs/gwendolynpy
    elif content.startswith("hello"):
        
        await message.channel.send(helloFunc(message.author.display_name))

    # Rolls dice with the roll_dice function from funcs/roll/dice.py
    elif content.startswith("roll"):
        if content == "roll" or content == "roll ":
            await message.channel.send(roll_dice(message.author.display_name))
        else:
            await message.channel.send(roll_dice(message.author.display_name, content.replace("roll","")))

    # Looks up a spell with the spellFunc function from funcs/lookup/lookuppy
    elif content.startswith("spell "):
        await message.channel.send(spellFunc(cap(content.replace("spell",""))))

    # Looks up a monster with the monsterFuncs() from funcs/lookup/lookuppy
    elif content.startswith("monster "):
        title, text1, text2, text3, text4, text5 = monsterFunc(cap(content.replace("monster","")))
        em1 = discord.Embed(title = title, description = text1, colour=0xDEADBF)

        # Sends the received information. Seperates into seperate messages if
        # there is too much text
        await message.channel.send(embed = em1)
        if text2 != "":
            if len(text2) < 2048:
                em2 = discord.Embed(title = "Special Abilities", description = text2, colour=0xDEADBF)
                await message.channel.send(embed = em2)
            else:
                em2 = discord.Embed(title = "Special Abilities", description = text2[:2048], colour=0xDEADBF)
                await message.channel.send(embed = em2)
                em2_2 = discord.Embed(title = "", description = text2[2048:], colour=0xDEADBF)
                await message.channel.send(embed = em2_2)
        if text3 != "":
            if len(text3) < 2048:
                em3 = discord.Embed(title = "Actions", description = text3, colour=0xDEADBF)
                await message.channel.send(embed = em3)
            else:
                em3 = discord.Embed(title = "Actions", description = text3[:2048], colour=0xDEADBF)
                await message.channel.send(embed = em3)
                em3_2 = discord.Embed(title = "", description = text3[2048:], colour=0xDEADBF)
                await message.channel.send(embed = em3_2)
        if text4 != "":
            if len(text4) < 2048:
                em4 = discord.Embed(title = "Reactions", description = text4, colour=0xDEADBF)
                await message.channel.send(embed = em4)
            else:
                em4 = discord.Embed(title = "Reactions", description = text4[:2048], colour=0xDEADBF)
                await message.channel.send(embed = em4)
                em4_2 = discord.Embed(title = "", description = text4[2048:], colour=0xDEADBF)
                await message.channel.send(embed = em4_2)
        if text5 != "":
            if len(text5) < 2048:
                em5 = discord.Embed(title = "Legendary Actions", description = text5, colour=0xDEADBF)
                await message.channel.send(embed = em5)
            else:
                em5 = discord.Embed(title = "Legendary Actions", description = text5[:2048], colour=0xDEADBF)
                await message.channel.send(embed = em5)
                em5_2 = discord.Embed(title = "", description = text5[2048:], colour=0xDEADBF)
                await message.channel.send(embed = em5_2)

    # Sends an image of the Senkulpa map
    elif content.startswith("map"):
        await message.channel.send("https://i.imgur.com/diMXXJs.jpg")

    # Finds a random image on the internet with the imageFuncs function from
    # funcs/gwendolynpy
    elif content.startswith("image"):
        await message.channel.send(imageFunc())

    # Sends information about a random movie with the movieFunc function from
    # funcs/other/movie.py
    elif content.startswith("movie"):
        async with message.channel.typing():
            title, plot, cover, cast = movieFunc()
            if title == "error":
                await message.channel.send("An error occurred. Try again")
            else:
                embed = discord.Embed(title=title, description=plot, color=0x24ec19)
                embed.set_thumbnail(url=cover)
                embed.add_field(name="Cast", value=cast,inline = True)
                await message.channel.send(embed = embed)

    # Generates a random name with the nameGen function from funcs/other/generators.py
    elif content.startswith("name"):
        await message.channel.send(nameGen())

    # Generates a random tavern name with the tavernGen function from funcs/other/generators.py
    elif content.startswith("tavern"):
        await message.channel.send(tavernGen())

    # Changes the "Playing this game" thing in Discord
    elif content.startswith("game "):
        gamePlaying = cap(content.replace("game ",""))
        game = discord.Game(gamePlaying)
        await client.change_presence(activity=game)

    # Rolls star wars dice with the parseRoll function from funcs/swfuncs/swroll.py
    elif content.startswith("swroll"):
        command = cap(content.replace("swroll",""))
        newMessage = parseRoll(message.author.display_name,command)
        messageList = newMessage.split("\n")
        for messageItem in messageList:
            await message.channel.send(messageItem)
    
    # Deals with Destiny Points and stuff
    elif content.startswith("swd"):
        command = content.replace("swd","")
        newMessage = parseDestiny(message.author.display_name,command)
        messageList = newMessage.split("\n")
        for messageItem in messageList:
            await message.channel.send(messageItem)

    # Rolls for critical injuries
    elif content.startswith("swcrit"):
        command = content.replace("swcrit","").replace(" ","").replace("+","")
        
        if command == "":
            command = 0

        try:
            newMessage = critRoll(int(command))
        except:
            newMessage = "Try using a number, stupid"

        messageList = newMessage.split("\n")
        for messageItem in messageList:
            await message.channel.send(messageItem)

    # Accesses and changes character sheet data with the parseChar function
    # from funcs/swfuncs/swchar.py 
    elif content.startswith("swchar") or content.startswith("sw"):
        command = string.capwords(content.replace("swchar","").replace("sw","").replace("+","+ ").replace("-","- ").replace(",",", "))
        title, desc = parseChar(message.author.display_name,command)
        if title != "":
            em1 = discord.Embed(title = title, description = desc, colour=0xDEADBF)
            await message.channel.send(embed = em1)
        else:
            await message.channel.send(desc)


    # Searches for a specific page on the Senkulpa Wiki
    elif content.startswith("wiki "):
        async with message.channel.typing():
            command = string.capwords(content.replace("wiki ",""))
            title, content, thumbnail = findWikiPage(command)
            if title != "":
                logThis("Sending the embedded message")
                content += "\n[Læs mere](https://senkulpa.fandom.com/da/wiki/"+title.replace(" ","_")+")"
                embed = discord.Embed(title = title, description = content, colour=0xDEADBF)
                if thumbnail != "":
                    embed.set_thumbnail(url=thumbnail)

                await message.channel.send(embed = embed)
            else:
                await message.channel.send(content)
    

    # Runs a trivia game
    elif content.startswith("trivia"):
        if content == "trivia" or content == "trivia ":
            question, answers, correctAnswer = triviaStart(str(message.channel))
            if answers != "":
                results = "**"+question+"**\n"
                for answer in range(len(answers)):
                    results += chr(answer+97) + ") "+answers[answer]+"\n"
                
                await message.channel.send(results)

                await asyncio.sleep(60)

                triviaCountPoints(str(message.channel))

                with open("resources/games/games.json", "r") as f:
                    data = json.load(f)
                
                del data["trivia questions"][str(message.channel)]
                with open("resources/games/games.json", "w") as f:
                    json.dump(data,f,indent=4)

                logThis("Time's up for the trivia question in "+str(message.channel))
                await message.channel.send("Time's up The answer was \""+chr(correctAnswer)+") "+answers[correctAnswer-97]+"\". Anyone who answered that has gotten 1 GwendoBuck")
            else:
                await message.channel.send(question)
        
        elif content.startswith("trivia "):
            command = content.replace("trivia ","")
            response = triviaAnswer(message.author.display_name.lower(),str(message.channel),command)
            if response.startswith("Locked in "):
                await message.add_reaction("👍")
            else:
                await message.channel.send(response)
        else:
            logThis("I didn't understand that")
            await message.channel.send("I didn't understand that")
    

    # Checks your GwendoBucks balance
    elif content.startswith("balance"):
        response = checkBalance(message.author.display_name.lower())
        if response == 1:
            new_message = message.author.display_name + " has " + str(response) + " GwendoBuck"
        else:
            new_message = message.author.display_name + " has " + str(response) + " GwendoBucks"
        await message.channel.send(new_message)
    
    # Gives money to other player
    elif content.startswith("give "):
        commands = content.split(" ")
        if len(commands) >= 3:
            try:
                amount = int(commands[2])
                response = giveMoney(message.author.display_name.lower(),commands[1],amount)
                await message.channel.send(response)
            except:
                logThis("I didn't quite understand that")
                await message.channel.send("I didn't quite understand that")
        else:
            logThis("I didn't understand that")
            await message.channel.send("I didn't understand that")
    
    # Runs a game of Blackjack
    elif content.startswith("blackjack"):
        # Starts the game
        if content == "blackjack" or content == "blackjack ":
            new_message = blackjackStart(str(message.channel))
            if new_message == "started":
                cardsLeft = 0
                with open("resources/games/blackjackCards.txt","r") as f:
                    for line in f:
                        cardsLeft += 1
                
                # Shuffles if not enough cards
                if cardsLeft < blackjackMinCards:
                    blackjackShuffle(blackjackDecks)
                    logThis("Shuffling the blackjack deck...")
                    await message.channel.send("Shuffling the deck...")

                new_message = "Blackjack game started. Use \""+commandPrefix+"blackjack bet [amount]\" to enter the game within the next 30 seconds."
                await message.channel.send(new_message)
                old_image = await message.channel.send(file = discord.File("resources/games/blackjackTables/blackjackTable"+str(message.channel)+".png"))

                await asyncio.sleep(30)

                gamedone = False

                with open("resources/games/games.json", "r") as f:
                    data = json.load(f)
                    if len(data["blackjack games"][str(message.channel)]["user hands"]) == 0:
                        gamedone = True
                        await message.channel.send("No one entered the game. Ending the game.")

                # Loop of game rounds
                while gamedone == False:
                    new_message, allStanding, gamedone = blackjackContinue(str(message.channel))
                    if new_message != "":
                        await message.channel.send(new_message)
                    if gamedone == False:
                        await old_image.delete()
                        old_image = await message.channel.send(file = discord.File("resources/games/blackjackTables/blackjackTable"+str(message.channel)+".png"))
                    if allStanding:
                        await asyncio.sleep(5)
                    else:
                        await asyncio.sleep(30)

                new_message = blackjackFinish(str(message.channel))
                await message.channel.send(new_message)
            else:
                await message.channel.send(new_message)

        # Entering game and placing bet
        elif content.startswith("blackjack bet"):
            commands = content.split(" ")
            try:
                amount = int(commands[2])
            except:
                logThis("I didn't understand that")
                response = "I didn't understand that"
            else:
                response = blackjackPlayerDrawHand(str(message.channel),message.author.display_name,amount)
            await message.channel.send(response)
        
        # Hitting
        elif content.startswith("blackjack hit"):
            if content == "blackjack hit" or content == "blackjack hit ":
                response = blackjackHit(str(message.channel),message.author.display_name)
            else:
                commands = content.split(" ")
                try:
                    handNumber = int(commands[2])
                except:
                    handNumber = 0
                response = blackjackHit(str(message.channel),message.author.display_name,handNumber)

            if response == "accept":
                await message.add_reaction("👍")
            else:
                await message.channel.send(response)

        # Standing
        elif content.startswith("blackjack stand"):
            response = blackjackStand(str(message.channel),message.author.display_name,0)
            if response == "accept":
                await message.add_reaction("👍")
            else:
                await message.channel.send(response)
        
        # Doubling bet
        elif content.startswith("blackjack double"):
            if content == "blackjack hit" or content == "blackjack hit ":
                response = blackjackDouble(str(message.channel),message.author.display_name)
            else:
                commands = content.split(" ")
                try:
                    handNumber = int(commands[2])
                except:
                    handNumber = 0
                response = blackjackDouble(str(message.channel),message.author.display_name,handNumber)

                await message.channel.send(response)
        
        # Splitting hand
        elif content.startswith("blackjack split"):
            response = blackjackSplit(str(message.channel),message.author.display_name)

            await message.channel.send(response)
        
        else:
            await message.channel.send("I didn't quite understand that")

    # Runs a game of four in a row
    elif content.startswith("fourinarow"):
        response, showImage = parseFourInARow(content.replace("fourinarow",""),str(message.channel),message.author.display_name)
        await message.channel.send(response)
        logThis(response)
        if showImage:
            await message.channel.send(file = discord.File("resources/games/4InARowBoards/board"+str(message.channel)+".png"))

# Makes files if they don't exist yet
makeFiles()

# Shuffling cards
blackjackShuffle(4)

# Gets secret bot token
with open("token.txt","r") as f:
    token = f.read().replace("\n","")

client = discord.Client()

# Logs in
@client.event
async def on_ready():
    logThis("Logged in as "+client.user.name+", "+str(client.user.id))
    game = discord.Game("Some weeb shit")
    await client.change_presence(activity=game)

# Reads messages and tests if they are Gwendolyn commands
@client.event
async def on_message(message):
    content = message.content
    if content.startswith(commandPrefix):
        logThis(message.author.display_name+" ran \""+content+"\"")
        await parseCommands(message,content.lower()[1:])

    # Is a bit sassy sometimes
    if ("gwendolyn" in message.content.lower() or message.content.startswith(commandPrefix)) and any(x in message.content.lower() for x in meanWords) and "ikke" not in message.content.lower() and "not" not in message.content.lower():
        logThis(message.author.display_name+" was a bit mean")
        emoji = random.choice(["😠", "🖕", "👎"])
        await message.add_reaction(emoji)

# Runs the whole shabang
client.run(token)
