import asyncio
import aiohttp
import aiocron
from async_timeout import timeout

import yaml
from yaml.loader import SafeLoader

import discord
import discord.utils
from discord import option
from discord.ext import commands

import mysql.connector
from mysql.connector import Error

import time
from datetime import date, datetime, tzinfo

import os

import flask

from easy_pil import Canvas, Editor, Font, Text, font, load_image_async
from PIL import Image, ImageDraw, ImageFont, ImageOps
import pytz
import socket

import importlib
import inspect


zeit = datetime.now()

time_date = zeit.strftime("%Y/%m/%d")
time_year = zeit.strftime("%Y")
time_month = zeit.strftime("%m")
time_day = zeit.strftime("%d")

time_time = zeit.strftime("%H:%M:%S")
time_hour = zeit.strftime("%H")
time_minute = zeit.strftime("%M")
time_second = zeit.strftime("%S")

time_datetime = zeit.strftime("%Y/%m/%d " "|" " %H:%M:%S")


TOKEN = "MTA5NDk3NTQzMjExOTU1MDA2Mw.GTLjcw.yfPzWjUHJgqycO9FG8YEANKY9R70KDboMorsRU"
bot = discord.Bot(intents=discord.Intents.all())

extensions = []
server = []

filelist = []


@bot.event
async def on_ready():
    print("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -")
    ratelimited = bot.is_ws_ratelimited()

    print(f"Is Bot Ratelimited: {ratelimited}")
    print("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -")

    global viewlist
    viewlist = []
    for i in range(0, 11, 1):
        view = discord.ui.View(timeout=None)
        viewlist.append(view)


    script_path = os.path.abspath(__file__)
    global path
    path = os.path.dirname(script_path)

    bot.path = path

    print(" ")
    print(f'{bot.user.name}: {time_datetime} | Im in Starting Process!')


    entries = os.listdir(fr'{path}/cogs')

    with open(fr'{path}/Configs/extensions.yaml', encoding='utf8') as f:
        data = yaml.load(f, Loader=SafeLoader)

    for entry in entries:
        try:
            if data["Config.Extensions"][f"{entry}"] == True:
                extensions.append(entry)
        except Exception as e:
            pass

    for i in extensions:
        startextension(i)
    try:
        await bot.sync_commands()
    except Exception:
        pass

    with open(fr'{path}/Configs/server.yaml', encoding='utf8') as f:
        data = yaml.load(f, Loader=SafeLoader)
        length = len(data["Config.Server"])

    for i in range(0, length, 1):
        if data["Config.Server"][i]["name"] and data["Config.Server"][i]["guild"] != "":
            server.append(data["Config.Server"][i]["name"])

    for i in server:
        for element in extensions:
            filename = element[:-3]

            try:
                with open(fr'{path}/Configs/{i}/{filename}.yaml', encoding='utf8') as f:
                    data = yaml.load(f, Loader=SafeLoader)
            except FileNotFoundError:
                filelist.append([i, filename])

            if data["Config.Enabled"] == True:
                filelist.append([i, filename])


    print(f'{bot.user.name}: {time_datetime} | Im adding the View Models!')


    for i in filelist:
        module = importlib.import_module(f"cogs.{i[1]}")
        for obj_name, obj in inspect.getmembers(module):
            if inspect.isclass(obj):
                if issubclass(obj, discord.ui.Button):
                    await snyc_items(obj, i[0])

    for view in viewlist:
        if len(view.children) != 0:
            bot.add_view(view)


    print(f'{bot.user.name}: {time_datetime} | Im Online and ready to interact!')


@bot.slash_command(name="extensions", description="start / stop or restart an extension.")
@option("function", description="Was soll ausgeführt werden?", choices=["start", "stop", "restart"])
@option("extension", description="Welche Extension wollen sie Starten?")
async def extension(
    ctx: discord.ApplicationContext,
    function= str,
    extension = str,
    ):
    allowed_ids = ['475256776296497153', '478916031222644736', '474560397547143169']
    if str(ctx.author.id) in allowed_ids:
        if function == "start":
            func = startextension(extension)
            await ctx.respond(f'{func}')
            try:
                await bot.sync_commands()
            except Exception:
                pass

        elif function == "stop":
            func = stopextension(extension)
            await ctx.respond(f'{func}')

        elif function == "restart":
            func = restartextension(extension)
            await ctx.respond(f'{func}')
            try:
                await bot.sync_commands()
            except Exception:
                pass

    else:
        ctx.respond('Your not allowed to do this action!')


def startextension(extensionname):
    try:
        bot.load_extension(fr'cogs.{extensionname[:-3]}')
    except Exception as e:
        backsend = f"There was an Error during the Process!\n```\n{e}\n```"
        return backsend
    backsend = f"The Process are successfully!\n```\nExtension {extensionname} was successfully loaded!\n```"
    return backsend


def stopextension(extensionname):
    try:
        bot.unload_extension(fr'cogs.{extensionname[:-3]}')
    except Exception as e:
        backsend = f"There was an Error during the Process!\n```\n{e}\n```"
        return backsend
    backsend = f"The Process are successfully!\n```\nExtension {extensionname} was successfully unloaded!\n```"
    return backsend


def restartextension(extensionname):
    try:
        bot.unload_extension(fr'cogs.{extensionname[:-3]}')
        time.sleep(1)
        bot.load_extension(fr'cogs.{extensionname[:-3]}')
    except Exception as e:
        backsend = f"There was an Error during the Process!\n```\n{e}\n```"
        return backsend
    backsend = f"The Process are successfully!\n```\nExtension {extensionname} was successfully reloaded!\n```"
    return backsend


async def check_status(servername):
    with open(fr'{path}/Configs/{servername}/rules.yaml', encoding='utf8') as f:
        data = yaml.load(f, Loader=SafeLoader)

    if data["Config.Enabled"] == True:
        return True

    else:
        return False
    

async def snyc_items(obj, servername):
    for view in viewlist:
        if len(view.children) < 25:
            view.add_item(obj(servername))
            return
        


bot.run(TOKEN)