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

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 Tempchannel(commands.Cog):
    
    def __init__(self, bot):
        self.bot = bot
        global path
        path = bot.path


    @commands.Cog.listener()
    async def on_voice_state_update(self, member, before, after):
        guild = member.guild
        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(guild.id) == str(item["guild"]))
            except StopIteration:
                return

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

        if after.channel is not None:
            for key in range(0, len(data["Config.Channel"]["creator"]), 1):
                for category, channels in data["Config.Channel"]["creator"][key].items():
                    if str(after.channel.id) in channels:
                        createback = await create_channel(member, after, category, servername)
                        if createback == True:
                            pass

            for key in range(0, len(data["Config.Channel"]["waiting"]), 1):
                for category, channels in data["Config.Channel"]["waiting"][key].items():
                    if str(after.channel.id) in channels:
                        annouceback = await announce_channel(self, member, category, servername)
                        if annouceback == True:
                            if data["Config.Ghostpings"] == True:


                                    ## Code to Check Supporttime


                                section = "waiting"
                                await ghost_ping(self, guild, category, servername)

                            else:
                                pass
                        
        if before.channel is not None and len(before.channel.members) == 0:
            await delete_channel(before, servername)

        else:
            pass


async def create_channel(member, after, category, servername):
    with open(fr'{path}/Configs/{servername}/tempchannel.yaml', encoding='utf8') as f:
        data = yaml.load(f, Loader=SafeLoader)
    if category in data["Config.Channel"]["output"]:
        channel = await after.channel.clone(name=data["Config.Channel"]["output"][category])
    else:
        channel = await after.channel.clone(name=f'🎧 | {member.name}')

    if channel is not None:
        await member.move_to(channel)

    role = member.guild.default_role if member.guild is not None else None
    if role:
        default_privileges = data["Config.Privileges"]["default"]
        user_privileges = data["Config.Privileges"]["user"]

        for key, value in default_privileges.items():
            await channel.set_permissions(role, **{key: value})

        for key, value in user_privileges.items():
            await channel.set_permissions(member, **{key: value})

        return True


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

    function = False
    for key in range(0, len(data["Config.Channel"]["creator"]), 1):
        for channels in data["Config.Channel"]["creator"][key].items():
            if str(before.channel.id) in channels:
                function = True
                break
        if function == True:
            break

    if function == False:
        for key in range(0, len(data["Config.Channel"]["waiting"]), 1):
            for channels in data["Config.Channel"]["creator"][key].items():
                if str(before.channel.id) in channels:
                    function = True
                    break
            if function == True:
                break

    if function == False:
        for channels in data["Config.Channel"]["neverdelete"]:
            if str(before.channel.id) in channels:
                function = True
                break

    if function == False:
        try:
            await before.channel.delete()
        except Exception:
            pass


async def announce_pannel(guild, member, before, after):
    pass


async def announce_channel(self, member, category, servername):
    with open(fr'{path}/Configs/{servername}/tempchannel.yaml', encoding='utf8') as f:
        data = yaml.load(f, Loader=SafeLoader)

    view = discord.ui.View(timeout=None)
    view.add_item(WaitingButtonAccept(servername))

    titel = data["Config.Text"]["waiting"][category]["header"]["title"]
    if "+X+" in titel:
        titel = titel.replace("+X+", member.name)

    descript = data["Config.Text"]["waiting"][category]["header"]["description"]
    if "+X+" in descript:
        descript = descript.replace("+X+", member.name)
    if "-X-" in descript:
        descript = descript.replace("-X-", member.mention)

    Embed = discord.Embed(
        title=titel,
        url=data["Config.Text"]["waiting"][category]["header"]["url"],
        description=descript,
        color=int(data["Config.Text"]["waiting"][category]["header"]["color"], 16)
    )
    Embed.set_footer(text=member.id)

    for i in range(0, len(data["Config.Channel"]["announce"][category]), 1):
        channel = self.bot.get_channel(int(data["Config.Channel"]["announce"][category][i]))
        await channel.send(embed=Embed, view=view)
    return True


async def ghost_ping(self, guild, category, servername):
    with open(fr'{path}/Configs/{servername}/tempchannel.yaml', encoding='utf8') as f:
        data = yaml.load(f, Loader=SafeLoader)

    for i in range(0, len(data["Config.Channel"]["announce"][category]), 1):
        channel = self.bot.get_channel(int(data["Config.Channel"]["announce"][category][i]))

        for i in range(0, len(data["Config.Roles"]), 1):
            role = guild.get_role(int(data["Config.Roles"][i]))
            ghostping = await channel.send(role.mention)
            await ghostping.delete(delay=0.4)


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

        super().__init__(
            emoji=f'{data["Config.Buttons"]["waitaccept"]["emoji"]}',
            label=f'{data["Config.Buttons"]["waitaccept"]["label"]}', 
            style=int(data["Config.Buttons"]["waitaccept"]["style"]),
            disabled=data["Config.Buttons"]["waitaccept"]["disabled"],
            custom_id=f'interaction:{self.__class__.__name__}',
        )

    async def callback(self, interaction: discord.Interaction):
        servername = self.server
        with open(fr'{path}/Configs/{servername}/tempchannel.yaml', encoding='utf8') as f:
            data = yaml.load(f, Loader=SafeLoader)

        user = interaction.user
        memberid = interaction.message.embeds[0].footer.text
        member = interaction.guild.get_member(int(memberid))

        for roleid in data["Config.Roles"]:
            role = interaction.guild.get_role(int(roleid))
            if role in interaction.user.roles:
                await interaction.message.delete()
                try:
                    channel = interaction.user.voice.channel
                    await member.move_to(channel)
                except Exception:
                    pass

                finally:
                    return

        else:
            if interaction.response.is_done():
                await interaction.followup.send("Your not allowed to move the Person!", ephemeral=True)
            else:
                await interaction.response.send_message("Your not allowed to move the Person!", ephemeral=True)


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