import discord
import os
import subprocess
import shutil
import pytz
import asyncio
from discord import app_commands
from datetime import datetime

client = discord.Client(intents=discord.Intents.default())
tree = app_commands.CommandTree(client)

token = "MTM0OTgyNDM5MDI1ODQ5MTQxMg.GIPuoK.N8DzB5-cleezsOYQwY1RV2e1eQVIWiBn2-7Njo"
guild = 1133100877037703209

valid_keys_file = "validkeys.txt"
accounts_file = "accounts.txt"

MAX_USERNAME_LENGTH = 16
MAX_KEY_LENGTH = 37

utc_now = datetime.now(pytz.utc)
formatted_time = utc_now.strftime('%Y-%m-%d %H:%M:%S UTC')

async def run_git_operations():
    atani_web_dir = os.path.join(os.path.dirname(os.getcwd()), "atani-web")
    atani_bot_dir = os.path.join(os.path.dirname(os.getcwd()), "atani-bot")
    
    subprocess.run(["git", "add", "*"], cwd=atani_web_dir)
    subprocess.run(["git", "commit", "-m", "New account registered"], cwd=atani_web_dir)
    subprocess.run(["git", "push"], cwd=atani_web_dir)

    subprocess.run(["git", "add", "*"], cwd=atani_bot_dir)
    subprocess.run(["git", "commit", "-m", "New account registered & key made invalid"], cwd=atani_bot_dir)
    subprocess.run(["git", "push"], cwd=atani_bot_dir)

@tree.command(
    name="register",
    description="Register an account using a valid key.",
    guild=discord.Object(id=guild)
)
async def register(interaction: discord.Interaction, username: str, key: str, discord_id: str = None):
    await interaction.response.defer(ephemeral=True)
	
    if len(username) > MAX_USERNAME_LENGTH:
        embed = discord.Embed(
            title="Username too long!",
            description=f"❌ The username must be {MAX_USERNAME_LENGTH} characters or less. You provided a username with {len(username)} characters.",
            color=16711680
        )
        await interaction.followup.send(embed=embed, ephemeral=True)
        return

    if len(key) > MAX_KEY_LENGTH:
        embed = discord.Embed(
            title="Key too long!",
            description=f"❌ The key must be {MAX_KEY_LENGTH} characters or less. You provided a key with {len(key)} characters.",
            color=16711680
        )
        await interaction.followup.send(embed=embed, ephemeral=True)
        return

    if discord_id:
        if not interaction.user.guild_permissions.manage_roles:
            await interaction.followup.send("You don't have the required permission to give roles!", ephemeral=True)
            return

        target_user = await interaction.guild.fetch_member(discord_id)
        if not target_user:
            await interaction.followup.send("Invalid Discord ID provided.", ephemeral=True)
            return
    else:
        target_user = interaction.user  # Default to the invoking user if no discord_id is passed

    user_id = str(target_user.id)

    if os.path.exists(accounts_file):
        with open(accounts_file, "r") as f:
            for line in f:
                existing_username, _, existing_id = line.strip().split(":")
                if existing_id == user_id:
                    embed = discord.Embed(
                        title="Already registered!",
                        description="☑️ You are already registered.",
                        color=29391
                    )
                    await interaction.followup.send(embed=embed, ephemeral=True)
                    return
                if existing_username == username:
                    embed = discord.Embed(
                        title="Username taken!",
                        description="❌ The username you entered is already being used by somebody. Please pick a unique username.",
                        color=16711680
                    )
                    await interaction.followup.send(embed=embed, ephemeral=True)
                    return

    if not os.path.exists(valid_keys_file):
        embed = discord.Embed(
            title="Invalid key!",
            description="❌ The key you entered is invalid or was already registered with. Please verify that your key is valid before submitting another request.",
            color=16711680
        )
        await interaction.followup.send(embed=embed, ephemeral=True)
        return

    with open(valid_keys_file, "r") as f:
        keys = f.readlines()

    key_found = False
    with open(valid_keys_file, "w") as f:
        for line in keys:
            if line.strip() == key:
                key_found = True  # Key is valid
            else:
                f.write(line)  # Keep other keys

    if not key_found:
        embed = discord.Embed(
            title="Invalid key!",
            description="❌ The key you entered is invalid or was already registered with. Please verify that your key is valid before submitting another request.",
            color=16711680
        )
        await interaction.followup.send(embed=embed, ephemeral=True)
        return

    with open(accounts_file, "a") as f:
        f.write(f"{username}:{key}:{user_id}\n")

    asyncio.create_task(run_git_operations())

    embed = discord.Embed(
        title="Registered!",
        description=f"🎉 You have successfully registered for **Atani Recode**! \n\nYour username is ``{username}`` and is locked to this discord account! If you wish to change your discord account please dm one of the developers to have your discord account relinked.",
        color=29391
    )

    try:
        await target_user.send(embed=embed)
    except discord.errors.Forbidden:
        # Skip sending DM if the user has DMs disabled
        pass

    log_embed = discord.Embed(
        title=f"{interaction.user.name} successfully registered!",
        description=f"<@{interaction.user.id}> executed the command `/register`\n🕛 At: ``{formatted_time}``",
        color=29391
    )

    log_channel = interaction.guild.get_channel(1342528823689875456)
    if log_channel:
        await log_channel.send(embed=log_embed)

    embed = discord.Embed(
        title="Registration Complete!",
        description=f"You have successfully registered! Check DMs for more information. Your username is ``{username}``.",
        color=29391
    )
    await interaction.followup.send(embed=embed, ephemeral=True)

@client.event
async def on_ready():
    await tree.sync(guild=discord.Object(id=guild))
    print("Ready!")

client.run(token)