from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, Http404, HttpResponse
from django.core.urlresolvers import reverse
from django.contrib import messages
from django.template.defaultfilters import slugify
from django.contrib.auth.decorators import permission_required

from modules.core.functions import *
from modules.core.decorators import *

#Forms
from forms import *

#Models
from models import *
from modules.payments.models import Payment
from modules.members.models import *

from modules.blocks.models import ContentBlock

from emails import *

@members_only
def theory_exam(request,form_slug):

    exam_form = get_object_or_404(TheoryExamForm,slug=form_slug)
    if not exam_form.enabled:
        messages.error(request,'Sorry, this exam form is not enabled')
        return HttpResponseRedirect('/my-locker/')

    member = get_object_or_404(Member,user=request.user)
    th_applications = TheoryExamApplication.objects.filter(member=member,exam=exam_form,complete=False)

    return render(request,'public/theory_exams/application.html',{'exam_form':exam_form,'th_applications':th_applications})

@members_only
def start_application(request,form_slug):

    exam_form = get_object_or_404(TheoryExamForm,slug=form_slug)
    if not exam_form.enabled:
        messages.error(request,'Sorry, this exam form is not enabled')
        return HttpResponseRedirect('/my-locker/')

    member = get_object_or_404(Member,user=request.user)
    exam_application = TheoryExamApplication(member=member, exam=exam_form, membership_number=member.membership_number, title=member.title, first_name=member.given_name, surname=member.surname, email_address=member.user.email, contact_number=member.telephone, dob=member.date_of_birth, job_title=member.job_title, current_employer=member.institution_company, mailing_address_1=member.address_1, mailing_address_2=member.address_2, mailing_town=member.town, mailing_county=member.county, mailing_postcode=member.postcode, mailing_country=member.country)
    exam_application.save()

    return HttpResponseRedirect(reverse('theory_exam_applicant',args=[exam_form.slug,exam_application.id]))

@members_only
def restart_application(request,form_slug,application_id):

    exam_form = get_object_or_404(TheoryExamForm,slug=form_slug)
    member = get_object_or_404(Member,user=request.user)
    exam_application = get_object_or_404(TheoryExamApplication,id=application_id,member=member)

    if not exam_form.enabled:
        messages.error(request,'Sorry, this exam form is not enabled')
        return HttpResponseRedirect('/my-locker/')

    if exam_application.complete:
        messages.error(request,'Sorry, you cannot restart an already complete application.')
    else:
        exam_application.delete()

        exam_application = TheoryExamApplication(member=member, exam=exam_form, membership_number=member.membership_number, title=member.title, first_name=member.given_name, surname=member.surname, email_address=member.user.email, contact_number=member.telephone, dob=member.date_of_birth, job_title=member.job_title, current_employer=member.institution_company, mailing_address_1=member.address_1, mailing_address_2=member.address_2, mailing_town=member.town, mailing_county=member.county, mailing_postcode=member.postcode, mailing_country=member.country)
        exam_application.save()

        messages.success(request,'Application has been Restarted.')

    return HttpResponseRedirect(reverse('theory_exam_applicant',args=[exam_form.slug,exam_application.id]))

@members_only
def delete_application(request,form_slug,application_id):

    exam_form = get_object_or_404(TheoryExamForm,slug=form_slug)
    member = get_object_or_404(Member,user=request.user)
    exam_application = get_object_or_404(TheoryExamApplication,id=application_id,member=member)

    try:
        exam_application.delete()
        messages.success(request,'Application Removed')

    except:
        messages.error(request,'Sorry, could not delete this application')

    return HttpResponseRedirect(reverse('theory_exam',args=[exam_form.slug]))

@members_only
def applicant_details(request,form_slug,application_id):

    exam_form = get_object_or_404(TheoryExamForm,slug=form_slug)
    member = get_object_or_404(Member,user=request.user)

    try:
        exam_application = TheoryExamApplication.objects.get(id=application_id,member=member)
    except TheoryExamApplication.DoesNotExist:
        messages.error(request,'Sorry, could not find this application.')
        return HttpResponseRedirect(reverse('theory_exam',args=[exam_form.slug]))

    if exam_application.complete:
        messages.error(request,'Sorry, you have already completed this application, you can review this application in your locker.')
        return HttpResponseRedirect(reverse('theory_exam',args=[exam_form.slug]))

    if exam_form.type == 'application':
        applicant_details_form = TheoryApplicantDetailsForm(instance=exam_application)
        applicant_details_form.fields['exam_choices'].queryset = ExamChoice.objects.filter(exam_form=exam_form)
        #applicant_details_form.fields['location'].queryset = ExamLocation.objects.filter(exam_form=exam_form)

    else:
        applicant_details_form = TheoryApplicantDetailsFormResit(instance=exam_application)
        applicant_details_form.fields['exam_choices'].queryset = ExamChoice.objects.filter(exam_form=exam_form)

    if request.POST:

        if exam_form.type == 'application':
            applicant_details_form = TheoryApplicantDetailsForm(request.POST,instance=exam_application)
            applicant_details_form.fields['exam_choices'].queryset = ExamChoice.objects.filter(exam_form=exam_form)
            #applicant_details_form.fields['location'].queryset = ExamLocation.objects.filter(exam_form=exam_form)

        else:
            applicant_details_form = TheoryApplicantDetailsFormResit(request.POST,instance=exam_application)
            applicant_details_form.fields['exam_choices'].queryset = ExamChoice.objects.filter(exam_form=exam_form)

        if applicant_details_form.is_valid():

            #try:
            applicant_details_form.save()
            #if exam_form.type == 'application':
            #    exam_application.location_name = exam_application.location.name
            #exam_application.exam_choice_name = exam_application.exam_choice.name
            exam_application.save()

            messages.success(request,'Information Saved')

            if exam_application.get_payment_amount() >= 0:
                return HttpResponseRedirect(reverse('theory_exam_payment',args=[exam_form.slug,exam_application.id]))
            else :
                exam_application.complete = True
                exam_application.paid = True
                exam_application.save()

                #email
                theory_application_form_completed(request,exam_application)

                #notification
                activity = UserActivity(member=member,type='exam-notification',title='Theory Exam Application Completed',text='You have completed an exam application for <strong>%s</strong>, to view this submission please go <a href="%s">here</a>.' % (exam_form,reverse('account_view_theory_exam_application',args=[exam_application.id])))
                activity.save()

                return HttpResponseRedirect(reverse('theory_exam_complete',args=[exam_form.slug]))

            #except:
            #    pass

    return render(request,'public/theory_exams/applicant-details.html',{'exam_form':exam_form,'exam_application':exam_application,'applicant_details_form':applicant_details_form})

@members_only
def payment(request,form_slug,application_id):

    exam_form = get_object_or_404(TheoryExamForm,slug=form_slug)
    member = get_object_or_404(Member,user=request.user)

    try:
        exam_application = TheoryExamApplication.objects.get(id=application_id,member=member)
    except TheoryExamApplication.DoesNotExist:
        messages.error(request,'Sorry, could not find this application.')
        return HttpResponseRedirect(reverse('theory_exam',args=[exam_form.slug]))

    if exam_application.complete:
        messages.error(request,'Sorry, you have already completed this application, you can review this application in your locker.')
        return HttpResponseRedirect(reverse('theory_exam',args=[exam_form.slug]))

    payment = Payment(member=member,type='theory_exam',theory_exam=exam_application)
    payment.save()

    if settings.DEVELOPMENT:
        payment.invoice = "Theory_Exam_Payment_%sD" % (payment.id)
    else :
        payment.invoice = "Theory_Exam_Payment_%s" % (payment.id)

    payment.save()

    secret_key = settings.WORLD_PAY_SECRET_KEY
    installation_id = settings.WORLD_PAY_INSTALLATION_ID
    redirect_url = "%s%s" % (settings.PAYMENT_URL,reverse('theory_exam_payment_process',args=[exam_form.slug,exam_application.id]))
    string = "%s:%s:%s:GBP:%s:%s" % (settings.WORLD_PAY_SECRET_KEY,settings.WORLD_PAY_INSTALLATION_ID,exam_application.get_payment_amount(),payment.invoice,redirect_url)
    import hashlib
    encrypted_string = hashlib.md5(string).hexdigest()

    if request.POST:
        #process other payments
        if request.POST.get('payment_method'):
            payment_method = request.POST['payment_method']
            exam_application.payment_type = payment_method
            exam_application.complete = True
            exam_application.completed_time = datetime.now()
            exam_application.save()

            #email to go here
            theory_application_form_completed_unpaid(request,exam_application)
            #send email

            return HttpResponseRedirect(reverse('theory_exam_complete',args=[exam_form.slug]))

    return render(request,'public/theory_exams/payment.html',{'exam_form':exam_form,'exam_application':exam_application,'payment':payment,'redirect_url':redirect_url,'encrypted_string':encrypted_string})

def payment_process(request,form_slug,application_id):

    exam_form = get_object_or_404(TheoryExamForm,slug=form_slug)

    callbackPW                              = request.POST.get('callbackPW', '')
    transStatus                             = request.POST.get('transStatus', '')
    authAmount                              = request.POST.get('authAmount', '')
    cartId                                  = request.POST.get('cartId', '')

    payment = get_object_or_404(Payment,invoice=cartId)

    errors = []
    error = False

    if not callbackPW or not transStatus or not authAmount or not cartId:
        error = True
        errors.append('Missing a Required Variable')

    if callbackPW != settings.WORLD_PAY_PASSWORD:
        error = True
        errors.append('World Pay Password Incorrect')

    if not errors:
        if transStatus == 'Y':

            if payment.status == 'pending':

                payment.status = 'complete'
                payment.amount = authAmount
                payment.save()

                exam_application = payment.theory_exam
                exam_application.paid = True
                exam_application.payment_type = 'credit_card'
                exam_application.complete = True
                exam_application.completed_time = datetime.now()
                exam_application.save()

                #email to go here
                theory_application_form_completed(request,exam_application)

                #notification
                activity = UserActivity(member=exam_application.member,type='exam-notification',title='Exam Application Completed',text='You have completed an exam application for <strong>%s</strong>, to view this submission please go <a href="%s">here</a>.' % (exam_form,reverse('account_view_theory_exam_application',args=[exam_application.id])))
                activity.save()

            next = "%s%s" % (settings.URL,reverse('theory_exam_payment_complete',args=[exam_form.slug,exam_application.id]))

        else:
            payment.status = 'rejected'
            payment.save()
            next = "%s%s" % (settings.URL,reverse('theory_exam_payment_failure',args=[exam_form.slug,application_id]))
    else:
        payment.status = 'rejected'
        payment.save()
        next = "%s%s" % (settings.URL,reverse('theory_exam_payment_failure',args=[exam_form.slug,application_id]))

    return render(request,'public/payment-redirect.html',{'next':next})

def payment_complete(request,form_slug,application_id):

    exam_form = get_object_or_404(TheoryExamForm,slug=form_slug)

    try:
        content_block = get_object_or_404(ContentBlock,slug='theory_exam_payment_complete')
    except:
        content_block = False

    return render(request,'public/theory_exams/payment-complete.html',{'exam_form':exam_form,'content_block':content_block})

def payment_failure(request,form_slug,application_id):

    exam_form = get_object_or_404(TheoryExamForm,slug=form_slug)
    messages.error(request,'Sorry, we could not take payment at this time, please try again below.')

    return HttpResponseRedirect(reverse('exam_application_payment',args=[exam_form.slug]))

@members_only
def complete(request,form_slug):

    exam_form = get_object_or_404(TheoryExamForm,slug=form_slug)
    member = get_object_or_404(Member,user=request.user)

    try:
        content_block = get_object_or_404(ContentBlock,slug='theory_exam_other_complete')
    except:
        content_block = False

    return render(request,'public/theory_exams/complete.html',{'exam_form':exam_form,'content_block':content_block})
