from django.views.generic import View
from django.shortcuts import render, reverse, redirect
from django.conf import settings
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from minecraft_manager.forms import ApplicationForm, TicketForm
import minecraft_manager.api.api as mcm_api
import minecraft_manager.utils as mcm_utils
import minecraft_manager.external.stats as mcm_stats
from minecraft_manager.models import Player
import random, yaml, os, json, datetime, pytz


def config():
    data = {}
    data['discord_invite'] = getattr(settings, "DISCORD_INVITE", "#")

    dynmap_url = getattr(settings, "DYNMAP_URL", "")
    data['dynmap_url'] = dynmap_url

    dynmap_static_url = getattr(settings, "DYNMAP_STATIC_URL", dynmap_url)
    data['dynmap_static_url'] = dynmap_static_url

    dynmap_world = getattr(settings, "WORLD", "world")
    data['dynmap_world'] = dynmap_world

    world_border = getattr(settings, "WORLD_BORDER", 100)
    data['world_border'] = world_border

    data['target'] = "_blank" if dynmap_url else "_self"

    x = random.randint(-world_border, world_border)
    data['x'] = x

    z = random.randint(-world_border, world_border)
    data['z'] = z

    uri = "?worldname={}&mapname=surface&zoom=5&x={}&y=64&z={}".format(dynmap_world, x, z)
    data['map_url'] = "{}{}".format(dynmap_url, uri)
    data['static_url'] = "{}{}".format(dynmap_static_url, uri)

    return data


def rules():
    path = os.path.join(settings.MINECRAFT_BASE_DIR, "plugins/MinecraftManager/config.yml")
    with open(path) as config_file:
        config = yaml.load(config_file)
    data = config['rules']['rules']
    if config['rules']['application']['validate']:
        data.append("The answer to the final question is \"{}\"".format(config['rules']['application']['answer']))

    return data


@method_decorator(csrf_exempt, name='dispatch')
class Apply(View):

    def get(self, request):
        form = ApplicationForm()
        return render(request, 'minecraft_manager/external/apply.html',
                      {'form': form.as_p(), 'rules': rules(), 'valid': False, 'map': config(),
                       'captcha': hasattr(settings, "CAPTCHA_SECRET")})

    def post(self, request):
        form = ApplicationForm(request.POST)
        valid_username = mcm_utils.validate_username(form.data['username'])
        captcha = mcm_utils.Captcha(request.POST)
        valid = form.is_valid()
        if valid and valid_username and captcha.success:
            app = form.save()
            msg = mcm_utils.build_application(app)
            mcm_api.discord_mcm(message='New Application!', embed=msg)
            mcm_api.plugin("application", "{0} {1}".format(form.data['username'], app.id))
        else:
            for error in captcha.errors:
                form.add_error(None, error)
            if not valid_username:
                form.add_error(None, "That username is not a premium Minecraft account")
        return render(request, 'minecraft_manager/external/apply.html',
                      {'form': form.as_p(), 'rules': rules(), 'valid': valid and valid_username and captcha.success, 'map': config(),
                       'captcha': hasattr(settings, "CAPTCHA_SECRET")})


@method_decorator(csrf_exempt, name='dispatch')
class Ticket(View):

    def get(self, request):
        form = TicketForm()
        return render(request, 'minecraft_manager/external/ticket.html',
                      {'form': form.as_p(), 'valid': False, 'map': config(),
                       'captcha': hasattr(settings, "CAPTCHA_SECRET")})

    def post(self, request):
        post = request.POST.copy()
        username = post['player']
        if 'player' in post and Player.objects.filter(username__iexact=post['player']).exists():
            player = Player.objects.get(username__iexact=post['player'])
            post.update({'player': player.id})
        form = TicketForm(post)
        captcha = mcm_utils.Captcha(request.POST)
        valid = form.is_valid()
        if 'player' not in post:
            # Why did I make Player nullable???
            valid = False
            form.add_error(None, "You must enter your IGN")
        if valid and captcha.success:
            ticket = form.save()
            # Create the message to send to Discord
            link = "{}".format(mcm_utils.url_path(settings.MCM_BASE_LINK, 'dashboard/ticket', ticket.id))
            msg = mcm_utils.build_ticket(ticket, link)
            mcm_api.discord_mcm(message="New Ticket", embed=msg, ping=True)
            mcm_api.plugin("ticket", "{0} {1} {2}".format(username, ticket.id, link))
        else:
            for error in captcha.errors:
                form.add_error(None, error)
            if 'player' in form.errors:
                form.errors['player'][0] = 'You must enter your IGN.'
        form.data = form.data.copy()
        form.data['player'] = username
        return render(request, 'minecraft_manager/external/ticket.html',
                      {'form': form.as_p(), 'valid': valid and captcha.success, 'map': config(),
                       'captcha': hasattr(settings, "CAPTCHA_SECRET")})


@method_decorator(csrf_exempt, name='dispatch')
class Stats(View):

    def get(self, request):
        get = request.GET
        results = None
        if 'stat' in get and get['stat']:
            results = mcm_stats.top_ten_stat(get['stat'])
        return render(request, 'minecraft_manager/external/stats_all.html', {'map': config(), 'stats': mcm_stats.get_names(sort=True), 'results': results})

    def post(self, request):
        pass


@method_decorator(csrf_exempt, name='dispatch')
class StatsPlayer(View):

    def get(self, request):
        get = request.GET
        results = None
        if 'username' in get and get['username']:
            if Player.objects.filter(username__iexact=get['username']).exists():
                uuid = Player.objects.get(username__iexact=get['username']).uuid
                results = mcm_stats.top_ten_player(uuid)
        if 'uuid' in get and get['uuid']:
            results = mcm_stats.top_ten_player(get['uuid'])
        return render(request, 'minecraft_manager/external/stats_single.html', {'map': config(), 'results': results})

    def post(self, request):
        pass



