import asyncio
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

from cogs.database import select_database, insert_database, update_database

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

## Class

class Whitelist(commands.Cog):
    
    def __init__(self, bot):
        self.bot = bot
        global path
        path = bot.path


    @commands.slash_command(name="whitelist", description="Senden der Whitelist")
    async def whitelist(
        self, ctx: discord.ApplicationContext
        ):
        with open(fr'{path}/Configs/server.yaml', encoding='utf8') as f:
            data = yaml.load(f, Loader=SafeLoader)
            try:
                servername = next(item["name"] for item in data["Config.Server"] if str(ctx.guild.id) == str(item["guild"]))
                checkback = await check_send(servername)
            except StopIteration:
                await ctx.respond("Error in Syntax", ephemeral=True)
                return

            if checkback != None:
                backsend = await send_whitelist(ctx, servername, checkback, self.bot)
                await ctx.respond(backsend, ephemeral=True)


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

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

        if data["Config.Redirekt"] == False:
            methode = "no_redirekt"
            if data["Config.Base"] == "Button":
                interactobject = "Button"

            if data["Config.Base"] == "Emoji":
                interactobject = "Emoji"

        if data["Config.Redirekt"] == True:
            methode = "redirekt"
            interactobject = "Button"

        checkback = [methode, interactobject]
        return checkback

    else:
        return


async def send_whitelist(ctx, servername, base, bot):
    with open(fr'{path}/Configs/{servername}/whitelist.yaml', encoding='utf8') as f:
        data = yaml.load(f, Loader=SafeLoader)

    guild = bot.get_guild(int(ctx.guild.id))
    channel = guild.get_channel(int(data["Config.Channel"]))

    methode = base[0]
    interactobject = base[1]

    length = len(data["Config.Text"][methode]["fields"])

    Embed = discord.Embed(
        title=data["Config.Text"][methode]["header"]["title"],
        url=data["Config.Text"][methode]["header"]["url"],
        description=data["Config.Text"][methode]["header"]["description"],
        color=int(data["Config.Text"][methode]["header"]["color"], 16)
    )
    for i in range(0, length, 1):
        Embed.add_field(
            name=data["Config.Text"][methode]["fields"][i]["name"],
            value=data["Config.Text"][methode]["fields"][i]["value"],
            inline=data["Config.Text"][methode]["fields"][i]["inline"]
        )
    Embed.set_footer(text=data["Config.Text"][methode]["footer"]["text"])

    if interactobject == "Button":
        view = discord.ui.View(timeout=None)
        view.add_item(WhitelistButton(servername))
        await channel.send(embed=Embed, view=view)

    if interactobject == "Emoji":
        await channel.send(embed=Embed)

    backsend = data["Config.Messages"]["message_send"]
    return backsend


async def check_role(interaction, servername):
    with open(fr'{path}/Configs/{servername}/whitelist.yaml', encoding='utf8') as f:
        data = yaml.load(f, Loader=SafeLoader)
    try:
        role = interaction.guild.get_role(int(data["Config.Roles"]["award"]["roleid"]))
    except Exception as e:
        backsend = data["Config.Messages"]["config_error_role"] + " ```\n" + e + "\n```"
        return backsend

    if role in interaction.user.roles:
        return True
    else:
        return False


async def set_roles(interaction, servername):
    with open(fr'{path}/Configs/{servername}/whitelist.yaml', encoding='utf8') as f:
        data = yaml.load(f, Loader=SafeLoader)
    try:
        role = interaction.guild.get_role(int(data["Config.Roles"]["award"]["roleid"]))
    except Exception as e:
        backsend = data["Config.Messages"]["config_error_role"] + " ```\n" + e + "\n```"
        return backsend
    
    await interaction.user.add_roles(role)
    backsend = data["Config.Messages"]["accept_granted"]
    return backsend


class WhitelistButton(discord.ui.Button):
    def __init__(self, servername):
        self.server = servername
        with open(fr'{path}/Configs/{servername}/whitelist.yaml', encoding='utf8') as f:
            data = yaml.load(f, Loader=SafeLoader)

        if data["Config.Redirekt"] == False and data["Config.Button"]["style"] != "5":
            super().__init__(
                emoji=f'{data["Config.Button"]["emoji"]}',
                label=f'{data["Config.Button"]["label"]}', 
                style=int(data["Config.Button"]["style"]),
                disabled=data["Config.Button"]["disabled"],
                custom_id=f'interaction:{self.__class__.__name__}',
            )

        else:
            super().__init__(
                url=f'{data["Config.Button"]["url"]}',
                label=f'{data["Config.Button"]["label"]}', 
                style=5,
                disabled=data["Config.Button"]["disabled"],
            )

    async def callback(self, interaction: discord.Interaction):
        user = interaction.user
        with open(fr'{path}/Configs/server.yaml', encoding='utf8') as f:
            data = yaml.load(f, Loader=SafeLoader)
            try:
                servername = next(item["name"] for item in data["Config.Server"] if str(interaction.guild.id) == str(item["guild"]))
            except StopIteration:
                return

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

        if data["Config.Require_Database"] == False:
            checkback_database = True
        else:
            sql = f"SELECT * FROM user WHERE member_id = '{interaction.user.id}'"
            checkback_database = await select_database(servername, sql)

        checkback_roles = await check_role(interaction, servername)

        if checkback_database == True and checkback_roles == True:
            backsend = data["Config.Messages"]["allready_accepted"]

        elif checkback_database == True and checkback_roles == False:
            backsend_roles = await set_roles(interaction, servername)
            backsend = backsend_roles

        else:
            backsend = data["Config.Messages"]["allready_accepted"]

        if interaction.response.is_done():
            await interaction.followup.send(backsend, ephemeral=True)
        else:
            await interaction.response.send_message(backsend, ephemeral=True)


def setup(bot):
    bot.add_cog(Whitelist(bot))