import requests
from django.shortcuts import render
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect
from django.template import RequestContext, loader
from django.urls import reverse
from django.contrib import auth
from .admin import UserCreationForm, PasswordChangeForm
from .tools import get_access_token
from .models import User

def get_experiment_names(request):
    """
    helper to get experiment names through API
    """
    if request.user.is_authenticated():
        api_url = request.build_absolute_uri(reverse('api:find_all_experiments'))
        access_token = get_access_token(request.user).token
        headers = {'Authorization': 'Bearer ' + access_token}
        r = requests.get(api_url, headers=headers).json()
        return r['names']

def delete_experiment(request, name):
    """
    helper to delete experiment through API
    """
    if request.user.is_authenticated():
        api_url = request.build_absolute_uri(reverse('api:delete_experiment'))
        access_token = get_access_token(request.user).token
        headers = {'Authorization': 'Bearer ' + access_token}
        params = {'name': name}
        r = requests.post(api_url, headers=headers, data=params).json()
        return r

def get_jobs(request, name):
    """
    helper to retrieve results of an experiment through API
    """
    if request.user.is_authenticated():
        api_url = request.build_absolute_uri(reverse('api:find_jobs'))
        access_token = get_access_token(request.user).token
        headers = {'Authorization': 'Bearer ' + access_token}
        r = requests.get(api_url, headers=headers, params={'name': name}).json()
        return r['jobs']

def index(request):
    request.session['exp_names'] = get_experiment_names(request)
    return render(request, 'app/index.html')

def message(request):
    messages = {'signedup': 'Your account has been created.',
                'showtoken': '',
                'failedsignin': 'Failed to authenticate the user.',
                'deletedexp': 'Your experiment has been deleted.',
                'faileddel': 'Failed to delete the experiment.',
                'none': ''}
    key = request.GET.get('key', 'none')
    message = messages[key]

    if key == 'signedup' or key == 'showtoken':
        # token was generated by create_auth_token automatically after account is created
        message += ' Your access token is ' + request.session['token']['string']
        message += ', which will be expired on ' + request.session['token']['expires']
        request.session['token'] = None # clear after display

    context = {'message': message}
    return render(request, 'app/index.html', context)

def login(request):
    username = request.POST['username']
    password = request.POST['password']
    user = auth.authenticate(username=username, password=password)
    if not user: # try with email again
        try:
            username = User.objects.get(email=username).username
            user = auth.authenticate(username=username, password=password)
        except User.DoesNotExist:
            pass
    if user:
        if user.is_active:
            auth.login(request, user)
            return HttpResponseRedirect('/app/')
    return HttpResponseRedirect('/app/message/?key=failedsignin') # back to home page

def logout(request):
    auth.logout(request)
    request.session['exp_names'] = None
    return HttpResponseRedirect('/app/') # back to home page

def token(request):
    token = get_access_token(user=request.user)
    request.session['token'] = {'string': token.token,
                                'expires': str(token.expires)}
    return HttpResponseRedirect('/app/message/?key=showtoken')

def signup(request):
    if request.method == 'GET':
        signup_form = UserCreationForm()
        context = {'signup_form': signup_form}
        return render(request, 'app/signup.html', context)
    elif request.method == 'POST':
        signup_form = UserCreationForm(request.POST)
        if signup_form.is_valid():
            user = signup_form.save() # save the account
            token = get_access_token(user=user)
            request.session['token'] = {'string': token.token,
                                        'expires': str(token.expires)}
            return HttpResponseRedirect('/app/message/?key=signedup')
        else:
            # to display validation error in the form
            context = {'signup_form': signup_form}
            return render(request, 'app/signup.html', context)
    return HttpResponse('Invalid request.')

def show(request, name):
    jobs = get_jobs(request, name)
    context = {'exp_name': name,
               'jobs': jobs}
    return render(request, 'app/show.html', context)

def delete(request, name):
    r = delete_experiment(request, name)
    if r and not 'error' in r:
        request.session['exp_names'] = get_experiment_names(request)
        return HttpResponseRedirect('/app/message/?key=deletedexp')
    return HttpResponseRedirect('/app/message/?key=faileddel')
