import discord, os, finnhub, platform, asyncio, traceback

from discord.ext import commands
from pymongo import MongoClient
from funcs import logThis, makeFiles, Money, Funcs, SwChar, SwDestiny, SwRoll, Games, Generators, BedreNetflix, NerdShit

commandPrefix = "!"

if platform.system() == "Windows":
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

class Credentials():
    def __init__(self):
        with open("credentials.txt","r") as f:
            data = f.read().splitlines()

        self.token = data[0][10:].replace(" ","")
        self.finnhubKey = data[1][16:].replace(" ","")
        self.wordnikKey = data[2][16:].replace(" ","")
        self.mongoDBUser = data[3][13:].replace(" ","")
        self.mongoDBPassword = data[4][17:].replace(" ","")
        self.wolfKey = data[5][19:].replace(" ","")
        self.radarrKey = data[6][15:].replace(" ","")
        self.sonarrKey = data[7][15:].replace(" ","")

class Options():
    def __init__(self):
        with open("options.txt","r") as f:
            data = f.read().splitlines()

        self.prefix = data[0][7:].replace(" ","")
        self.testing = (data[1][8:].replace(" ","").lower() == "true")

class Gwendolyn(commands.Bot):
    def __init__(self):
        self.options = Options()
        self.credentials = Credentials()
        self.finnhubClient = finnhub.Client(api_key = self.credentials.finnhubKey)
        self.MongoClient = MongoClient(f"mongodb+srv://{self.credentials.mongoDBUser}:{self.credentials.mongoDBPassword}@gwendolyn.qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority")

        if self.options.testing:
            logThis("Testing mode")
            self.database = self.MongoClient["Gwendolyn-Test"]
        else:
            self.database = self.MongoClient["Gwendolyn"]

        self.swchar = SwChar(self)
        self.swroll = SwRoll(self)
        self.swdestiny = SwDestiny(self)

        self.generator = Generators()
        self.bedreNetflix = BedreNetflix(self)
        self.nerdShit = NerdShit(self)

        Games(self)

        self.money = Money(self)
        self.funcs = Funcs(self)

        super().__init__(command_prefix=commandPrefix, case_insensitive=True)

# Creates the required files
makeFiles()

# Creates the Bot
client = Gwendolyn()

# 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)

# Logs when user sends a command
@client.event
async def on_command(ctx):
    logThis(f"{ctx.message.author.display_name} ran {ctx.message.content}")

# Logs if a command experiences an error
@client.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandNotFound):
        await ctx.send("That's not a command (error code 001)")
    elif isinstance(error,commands.errors.MissingRequiredArgument):
        logThis(f"{error}",str(ctx.message.channel.id))
        await ctx.send("Missing command parameters (error code 002). Try using `!help [command]` to find out how to use the command.")
    else:
        exception = traceback.format_exception(type(error), error, error.__traceback__)
        stopAt = "\nThe above exception was the direct cause of the following exception:\n\n"
        if stopAt in exception:
            index = exception.index(stopAt)
            exception = exception[:index]

        exceptionString = "".join(exception)
        logThis([f"exception in command !{ctx.command}", f"{exceptionString}"],str(ctx.message.channel.id), 40)
        await ctx.send("Something went wrong (error code 000)")

#Loads cogs
for filename in os.listdir("./cogs"):
    if filename.endswith(".py"):
        client.load_extension(f"cogs.{filename[:-3]}")

try:
    # Runs the whole shabang
    client.run(client.credentials.token)
except:
    logThis("Could not log in. Remember to write your bot token in the credentials.txt file")
