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 *

#Forms
from forms import *

#Models
from models import *

from emails import *

from filetransfers.api import serve_file
import csv

@permission_required('admin_users.can_access_exam_applications')
def theory_exams(request):

    enabled_exam_forms = TheoryExamForm.objects.filter(enabled=True)
    disabled_exam_forms = TheoryExamForm.objects.filter(enabled=False)

    return render(request,'admin/theory_exams/exam-forms.html',{'enabled_exam_forms':enabled_exam_forms,'disabled_exam_forms':disabled_exam_forms})

@permission_required('admin_users.can_access_exam_applications')
def add_theory_exam(request):

    exam_form_form = TheoryExamFormForm()

    if request.POST:
        exam_form_form = TheoryExamFormForm(request.POST)

        if exam_form_form.is_valid():
            #try:
            exam_form = exam_form_form.save(commit=False)
            exam_form.slug = slugify_unique(exam_form.name,TheoryExamForm)
            exam_form.save()

            messages.success(request,'Exam Form has been Created')
            return HttpResponseRedirect(reverse('admin_theory_exams'))

            #except:
            #    messages.error(request,'Could not create Exam Form')

    return render(request,'admin/theory_exams/add-exam-form.html',{'exam_form_form':exam_form_form})

@permission_required('admin_users.can_access_exam_applications')
def edit_theory_exam(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    exam_form_form = TheoryExamFormForm(instance=exam_form)

    if request.POST:
        exam_form_form = TheoryExamFormForm(request.POST,instance=exam_form)

        if exam_form_form.is_valid():
            try:
                exam_form_form.save()

                messages.success(request,'Exam Form has been Updated')
                return HttpResponseRedirect(reverse('admin_theory_exams'))

            except:
                messages.error(request,'Could not update Exam Form')

    return render(request,'admin/theory_exams/add-exam-form.html',{'exam_form':exam_form,'exam_form_form':exam_form_form})

@permission_required('admin_users.can_access_exam_applications')
def delete_theory_exam(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)

    try:
        exam_form.delete()
        messages.success(request,'Exam form has been deleted')
    except:
        messages.error(request,'Could not delete Exam Form')

    return HttpResponseRedirect(reverse('admin_theory_exams'))


@permission_required('admin_users.can_access_exam_applications')
def enable_theory_exam(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)

    try:
        exam_form.enabled=True
        exam_form.save()
        messages.success(request,'Exam form has been enabled')
    except:
        messages.error(request,'Could not enable Exam Form')

    return HttpResponseRedirect(reverse('admin_theory_exams'))

@permission_required('admin_users.can_access_exam_applications')
def disable_theory_exam(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)

    try:
        exam_form.enabled=False
        exam_form.save()
        messages.success(request,'Exam form has been disabled')
    except:
        messages.error(request,'Could not disable Exam Form')

    return HttpResponseRedirect(reverse('admin_theory_exams'))

@permission_required('admin_users.can_access_exam_applications')
def locations(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    locations = ExamLocation.objects.filter(exam_form=exam_form)

    return render(request,'admin/theory_exams/locations/locations.html',{'exam_form':exam_form,'locations':locations})

@permission_required('admin_users.can_access_exam_applications')
def add_location(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    location_form = ExamLocationForm()

    if request.POST:
        location_form = ExamLocationForm(request.POST)

        if location_form.is_valid():
            try:
                location = location_form.save(commit=False)
                location.exam_form = exam_form
                location.save()

                messages.success(request,'Location has been Created')
                return HttpResponseRedirect(reverse('admin_theory_exam_locations',args=[exam_form.id]))

            except:
                messages.error(request,'Could not create Exam Form')

    return render(request,'admin/theory_exams/locations/add-location.html',{'exam_form':exam_form,'location_form':location_form})


@permission_required('admin_users.can_access_exam_applications')
def edit_location(request,exam_id,location_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    location = get_object_or_404(ExamLocation,id=location_id)
    location_form = ExamLocationForm(instance=location)

    if request.POST:
        location_form = ExamLocationForm(request.POST,instance=location)

        if location_form.is_valid():
            try:
                location_form.save()

                messages.success(request,'Location has been Updated')
                return HttpResponseRedirect(reverse('admin_theory_exam_locations',args=[exam_form.id]))

            except:
                messages.error(request,'Could not update Location')

    return render(request,'admin/theory_exams/locations/edit-location.html',{'exam_form':exam_form,'location':location,'location_form':location_form})

@permission_required('admin_users.can_access_exam_applications')
def delete_location(request,exam_id,location_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    location = get_object_or_404(ExamLocation,id=location_id)

    try:
        location.delete()
        messages.success(request,'Exam form has been deleted')
    except:
        messages.error(request,'Could not delete Exam Form')

    return HttpResponseRedirect(reverse('admin_theory_exam_locations',args=[exam_form.id]))


@permission_required('admin_users.can_access_exam_applications')
def exam_choices(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    exam_choices = ExamChoice.objects.filter(exam_form=exam_form)

    return render(request,'admin/theory_exams/exam_choices/choices.html',{'exam_form':exam_form,'exam_choices':exam_choices})

@permission_required('admin_users.can_access_exam_applications')
def add_exam_choice(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    exam_choice_form = ExamChoiceForm()

    if request.POST:
        exam_choice_form = ExamChoiceForm(request.POST)

        if exam_choice_form.is_valid():
            try:
                exam_choice = exam_choice_form.save(commit=False)
                exam_choice.exam_form = exam_form
                exam_choice.save()

                messages.success(request,'Location has been Created')
                return HttpResponseRedirect(reverse('admin_theory_exam_choices',args=[exam_form.id]))

            except:
                messages.error(request,'Could not create Exam Form')

    return render(request,'admin/theory_exams/exam_choices/add-choice.html',{'exam_form':exam_form,'choice_form':exam_choice_form})


@permission_required('admin_users.can_access_exam_applications')
def edit_exam_choice(request,exam_id,choice_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    exam_choice = get_object_or_404(ExamChoice,id=choice_id)
    exam_choice_form = ExamChoiceForm(instance=exam_choice)

    if request.POST:
        exam_choice_form = ExamChoiceForm(request.POST,instance=exam_choice)

        if exam_choice_form.is_valid():
            try:
                exam_choice_form.save()

                messages.success(request,'Location has been Updated')
                return HttpResponseRedirect(reverse('admin_theory_exam_choices',args=[exam_form.id]))

            except:
                messages.error(request,'Could not update Location')

    return render(request,'admin/theory_exams/exam_choices/edit-choice.html',{'exam_form':exam_form,'exam_choice':exam_choice,'choice_form':exam_choice_form})

@permission_required('admin_users.can_access_exam_applications')
def delete_exam_choice(request,exam_id,choice_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    exam_choice = get_object_or_404(ExamChoice,id=choice_id)

    try:
        exam_choice.delete()
        messages.success(request,'Exam form has been deleted')
    except:
        messages.error(request,'Could not delete Exam Form')

    return HttpResponseRedirect(reverse('admin_theory_exam_choices',args=[exam_form.id]))


@permission_required('admin_users.can_access_exam_applications')
def exam_applicants(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)

    complete_applicants = TheoryExamApplication.objects.filter(exam=exam_form,complete=True,paid=True)
    unpaid_applicants = TheoryExamApplication.objects.filter(exam=exam_form,complete=True,paid=False)
    incomplete_applicants = TheoryExamApplication.objects.filter(exam=exam_form,complete=False)

    return render(request,'admin/theory_exams/applicants/applicants.html',{'exam_form':exam_form,'complete_applicants':complete_applicants,'unpaid_applicants':unpaid_applicants,'incomplete_applicants':incomplete_applicants})


@permission_required('admin_users.can_access_exam_applications')
def download_applicants(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    complete_applicants = TheoryExamApplication.objects.filter(exam=exam_form,complete=True,paid=True)

    fields = ['Submitted','Membership Number','Title','First Name','Surname','Email Address','Contact Number','DOB','Job Title','Current Employer','Employment Start Date','Work Address 1','Work Address 2','Work Town','Work County','Work Postcode','Work Country','Other Sites Worked', 'Mailing Address 1','Mailing Address 2', 'Mailing Town','Mailing County','Mailing Postcode','Mailing Country']

    for choice in ExamChoice.objects.filter(exam_form=exam_form):
        fields.append(choice)

    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = "attachment; filename=exam_applicants.csv"

    writer = csv.writer(response)
    writer.writerow(fields)

    for applicant in complete_applicants:
        if not applicant.membership_number:
            applicant.membership_number = applicant.member.membership_number
            applicant.save()
        fields = [applicant.completed_time,applicant.membership_number,applicant.title,applicant.first_name,applicant.surname,applicant.email_address,applicant.contact_number,applicant.dob,applicant.job_title,applicant.current_employer,applicant.employment_start_date,applicant.work_address_1,applicant.work_address_2,applicant.work_town,applicant.work_county,applicant.work_postcode,applicant.work_country, applicant.mailing_address_1,applicant.mailing_address_2,applicant.mailing_town,applicant.mailing_county,applicant.mailing_postcode,applicant.mailing_country]

        for choice in ExamChoice.objects.filter(exam_form=exam_form):
            if choice in applicant.exam_choices.all():
                fields.append("Y")
            else:
                fields.append("N")

        writer.writerow([unicode(s).encode("utf-8") for s in fields])

    return response

@permission_required('admin_users.can_access_exam_applications')
def download_external(request,exam_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    complete_applicants = TheoryExamApplication.objects.filter(exam=exam_form,complete=True,paid=True)

    fields = ['Amount','Salutation/Title','First Name','Middle Name','Last Name','Gender (M/F)','Birth date (dd/mm/yyyy)', 'Employer (Optional)','Address','City','State/County','Zip/Postal Code','Phone Number','Country','Email','SVTGBI ID #','Physics/Tech/Both']

    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = "attachment; filename=exam_applicants_external.csv"

    writer = csv.writer(response)
    writer.writerow(fields)

    for applicant in complete_applicants:
        exam_type = ""
        for choice in applicant.exam_choices.all():
            if exam_type:
                exam_type = 'Both'
            else:
                exam_type = choice.get_type_display()
        fields = [applicant.get_payment_amount(),applicant.title,applicant.first_name,'',applicant.surname,'',applicant.dob,applicant.current_employer,applicant.work_address_1,applicant.work_town,applicant.work_county,applicant.work_postcode,applicant.contact_number,applicant.work_country,applicant.email_address,applicant.membership_number,exam_type]

        writer.writerow([unicode(s).encode("utf-8") for s in fields])

    return response

@permission_required('admin_users.can_access_exam_applications')
def view_application(request,exam_id,application_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    application = get_object_or_404(TheoryExamApplication,id=application_id)

    return render(request,'admin/theory_exams/applicants/view-application.html',{'exam_form':exam_form,'application':application})

@permission_required('admin_users.can_access_exam_applications')
def delete_application(request,exam_id,application_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    application = get_object_or_404(TheoryExamApplication,id=application_id)

    try:
        application.delete()
        messages.success(request,'Application has been deleted.')
    except:
        messages.error(request,'Could not delete application.')

    return HttpResponseRedirect(reverse('admin_theory_exam_applicants',args=[exam_form.id]))


@permission_required('admin_users.can_access_exam_applications')
def mark_paid_application(request,exam_id,application_id):

    exam_form = get_object_or_404(TheoryExamForm,id=exam_id)
    application = get_object_or_404(TheoryExamApplication,id=application_id)

    #try:
    application.paid = True
    application.save()

    theory_application_form_paid(request,application)
    messages.success(request,'Application has been marked as paid')

    #except:
    #    application.paid = False
    #    application.save()

    #    messages.error(request,'Could not mark application as paid')

    return HttpResponseRedirect(reverse('admin_theory_exam_applicants',args=[exam_form.id]))
