import json
import re
import discord
from discord.ext import commands
from dotenv import load_dotenv
from os import getenv
from github_connector import create_or_update_file, delete_file


load_dotenv("./.env")

CHANNEL_ID = int(getenv("CHANNEL_ID"))
MAINTAINERS = json.loads(getenv("MAINTAINERS"))
DISCORD_TOKEN = getenv("DISCORD_TOKEN")

print(MAINTAINERS)

# Intents are required to listen to events like messages
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
intents.reactions = True
intents.dm_messages = True

# Create an instance of the Bot
bot = commands.Bot(command_prefix="!", intents=intents)


def getFileName(event):
    return f"{event.start_time.strftime("%Y-%m-%d")}_{event.name}"


def getFilePath(event):
    return f"_events/{event.start_time.strftime("%Y")}/discord-event-{event.id}.md"


def getEventYML(event):
    return f'# event imported from discord manual changes may be overwritten\n---\n \nlayout: event\ntitle: "{event.name}"\nauthor: "Netz39 e.V." \nevent:\n  start: {event.start_time.strftime("%Y-%m-%d %H:%M:%S")} \n  end:   {event.end_time.strftime("%Y-%m-%d %H:%M:%S")} \n  organizer: "Netz39 Team <kontakt@netz39.de>" \n  location: "Leibnizstr. 18, 39104 Magdeburg"\n---'


def addMaintainer(maintainer):
    MAINTAINERS.append(maintainer)
    with open(".env", "r") as fileR:
        # read a list of lines into data
        data = fileR.readlines()
        data[6] = f"MAINTAINERS='{json.dumps(MAINTAINERS)}'"
    with open(".env", "w") as fileW:
        fileW.writelines(data)


async def handleEvent(event):
    eventYML = getEventYML(event)
    if "netz39" in event.location.lower() or (
        "leibniz" in event.location.lower() and "18" in event.location
    ):
        if event.creator_id in MAINTAINERS:
            create_or_update_file(
                getFilePath(event),
                eventYML,
                f"new event: {getFileName(event)}",
            )
            channel = bot.get_channel(CHANNEL_ID)
            await channel.send(
                f"📅 New event '{event.name}' on {event.start_time.strftime("%Y-%m-%d")}."
            )
        else:
            eventJSON = json.dumps(
                {
                    "yml": eventYML,
                    "path": getFilePath(event),
                    "fileName": getFileName(event),
                    "name": event.name,
                    "date": event.start_time.strftime("%Y-%m-%d"),
                },
                indent=2,
            )
            for maintainer in MAINTAINERS:
                user = await bot.fetch_user(event.creator_id)
                await sendDm(
                    maintainer,
                    f"{user.name} added a new Event on {event.start_time.strftime("%Y")}: {event.name}. Like this message to approve.\n\n\n```json\n{eventJSON}```",
                )


# Event: When the bot is ready
@bot.event
async def on_ready():
    print(f"Logged in as {discord.user}")


# Command: !hello
@bot.command()
async def hello(ctx):
    await ctx.send(
        "Hello, I am a bot to add events from discord to the Netz39 calendar on the website!"
    )


@bot.event
async def on_ready():
    print(f"Logged in as {bot.user}")
    channel = bot.get_channel(CHANNEL_ID)
    await channel.send("Hello everyone! I'm online and ready to go! 📅")


@bot.event
async def on_scheduled_event_update(event):
    await handleEvent(event)


@bot.event
async def on_scheduled_event_create(event):
    await handleEvent(event)


async def sendDm(userID, message):
    user = await bot.fetch_user(userID)
    await user.send(message)


@bot.event
async def on_reaction_add(reaction, user):
    if not user.id in MAINTAINERS:
        return  # Ignore non-maintainers
    if user.bot:
        return  # Ignore bot reactions

    if (
        isinstance(reaction.message.channel, discord.DMChannel)
        and reaction.message.author.bot
    ):  # Check if it's a DM and from the bot
        if reaction.emoji == "👍":
            messageJSON = json.loads(
                re.search(
                    "(?s)(?<=```json).*?(?=```)", reaction.message.content
                ).group()
            )
            create_or_update_file(
                messageJSON["path"],
                messageJSON["yml"],
                f"new event: {messageJSON["fileName"]}",
            )
            channel = bot.get_channel(CHANNEL_ID)
            await channel.send(
                f"📅 New event '{messageJSON["name"]}' on {messageJSON["date"]}."
            )


@bot.event
async def on_message(message):
    if isinstance(message.channel, discord.DMChannel):
        global MAINTAINERS
        author = message.author
        if "add maintainer" in message.content.lower() and author.id in MAINTAINERS:
            newMaintainer = message.content.lower().replace("add maintainer ", "")
            if not newMaintainer in MAINTAINERS:
                addMaintainer(int(newMaintainer))
                await sendDm(
                    newMaintainer,
                    "You are now a Maintainer for posthorn! Create an event located at 'Netz39 e.V.' and it will be added to the calendar.",
                )
                await message.channel.send("Maintainer added!")
    await bot.process_commands(message)


@bot.event
async def on_scheduled_event_delete(event):
    delete_file(getFilePath(event))
    channel = bot.get_channel(CHANNEL_ID)
    await channel.send(f"❌ Event has been canceled: {event.name}")


bot.run(DISCORD_TOKEN)