import os
import ast
import time
from datetime import datetime, timedelta
import asyncio

import sgfengine

import discord
from discord.ext import commands

# We don't use fancy slash commands here. It seems there is this library for python but it looks a bit more involved.
# https://pypi.org/project/discord-py-slash-command/

intents = discord.Intents.default()
#intents.message_content = True

bot = commands.Bot(command_prefix='$', help_command=None, intents=intents)

# People who can start and resign games :O
admins=[]
awesome_server_id=
permitted_channel_id=

player_id= 0
start_time = 0

with open("token.txt") as f:
    token = f.readlines()[0] # Get your own token and put it in token.txt

@bot.command()
async def help(ctx):
    if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id:
        return
    
    await ctx.send(
            '$help : shows this help\n\n'+

            '$play <move>: play a move. For example, `$play Q16`. Passing is not implemented!\n'+
            '$edit <move>: if you make a mistake in your move\n\n'+

            '$sgf: get the sgf file of the game\n'+
            '$board: shows the current board\n'+

            '$newgame <handicap> <komi>: starts a game in this channel (admin only!)\n'+
            '$resign <B/W>: <B/W> resigns the game in this channel. It returns its sgf file (admin only!)'
            )
    # ctx has guild, message, author, send, and channel (?)

@bot.command()
async def play(ctx, arg):
    if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id:
        return

    channel_id= ctx.channel.id
    user = ctx.author
    guild= ctx.guild

    global player_id
    global start_time

    if not os.path.exists(str(channel_id)+".sgf"):
        await ctx.send("No active game in this channel!")
        return


    if (player_id == user.id):
        await ctx.send("No two consecutive moves by the same player!")
        return

    elapsed_time = time.time() - start_time
    print(elapsed_time)
    if elapsed_time < 1:
        await ctx.send("One second per move!")
        return

    legal_moves=[chr(col+ord('A')-1)+str(row) for col in range(1,21) if col!=9 for row in range(1,20)]
    legal_moves+=[chr(col+ord('a')-1)+str(row) for col in range(1,21) if col!=9 for row in range(1,20)]
    if arg not in legal_moves:
        await ctx.send("I don't understand the move! Please input it in the format `$play Q16`")
        return

    try:
        sgfengine.play_move(str(channel_id), arg, user.display_name)
    except ValueError as e:
        await ctx.send(str(e))
        return

    player_id=user.id
    start_time = time.time()
 
    file = discord.File(str(ctx.channel.id)+".png")

    await ctx.send(file=file)


@bot.command()
async def edit(ctx, arg):
    if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id:
        return
    channel_id= ctx.channel.id
    user = ctx.author
    guild= ctx.guild

    if not os.path.exists(str(channel_id)+".sgf"):
        await ctx.send("No active game in this channel!")
        return

    colour= sgfengine.next_colour(str(channel_id))

    legal_moves=[chr(col+ord('A')-1)+str(row) for col in range(1,21) if col!=9 for row in range(1,20)]
    legal_moves+=[chr(col+ord('a')-1)+str(row) for col in range(1,21) if col!=9 for row in range(1,20)]
    if arg not in legal_moves:
        await ctx.send("I don't understand the move! Please input it in the format `$play Q16`")
        return

    try:
        sgfengine.play_move(str(channel_id), arg, user.display_name, True)
    except ValueError as e:
        await ctx.send(str(e))
        return

    file = discord.File(str(ctx.channel.id)+".png")
    await ctx.send(file=file)

@bot.command()
async def board(ctx):
    if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id:
        return

    channel_id= ctx.channel.id
    user = ctx.author
    guild= ctx.guild

    if not os.path.exists(str(channel_id)+".sgf"):
        await ctx.send("No active game in this channel!")
        return

    os.system("/home/nik/.cargo/bin/sgf-render -f png --style fancy --label-sides nesw -o "+str(channel_id)+".png -n last "+str(channel_id)+".sgf")
    file = discord.File(str(ctx.channel.id)+".png")

    await ctx.send(file=file)

@bot.command()
async def sgf(ctx):
    if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id:
        return
    
    file = discord.File(str(ctx.channel.id)+".sgf")
    await ctx.send(file=file)

@bot.command()
async def newgame(ctx, handicap=0, komi=6.5):
    if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id:
        return

    channel_id= ctx.channel.id
    user = ctx.author

    if user.id not in admins:
        await ctx.send("You don't have permissions for this!")
        return

    sgfengine.new_game(str(channel_id), handicap, komi)
  
    os.system("/home/nik/.cargo/bin/sgf-render -f png --style fancy --label-sides nesw -o "+str(channel_id)+".png -n last "+str(channel_id)+".sgf")

    file = discord.File(str(channel_id)+".png")
 
    await ctx.send(file=file, content="A new game has started! Play with `$play <move>`")

@bot.command()
async def resign(ctx, arg):
    if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id:
        return

    channel_id= ctx.channel.id
    user = ctx.author

    if user.id not in admins:
        await ctx.send("You don't have permissions for this!")
        return

    if arg not in ["W","B"]:
        await ctx.send("Unrecognized colour! Please try `$resign <B/W>` to resign as Black/White")
        return

    now=datetime.now()
    file_name= "rengo_"+now.strftime("%Y_%m_%d_%H_%M_%S_")+ctx.channel.name+".sgf"

    sgfengine.resign(str(channel_id), arg, file_name)

    file = discord.File(file_name)
    await ctx.send(file=file, content=("Black" if arg=="W" else "White")+" wins!")


print("Running")
bot.run(token)