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 exam_forms(request):

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

    return render(request,'admin/exam_applications/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_exam_form(request):

    exam_form_form = ExamFormForm()

    if request.POST:
        exam_form_form = ExamFormForm(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,ExamForm)
            exam_form.save()

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

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

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


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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    exam_form_form = ExamFormForm(instance=exam_form)

    if request.POST:
        exam_form_form = ExamFormForm(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_exam_forms'))

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

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

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

    exam_form = get_object_or_404(ExamForm,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_exam_forms'))


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

    initial_exam_form = get_object_or_404(ExamForm,id=exam_id)
    exam_form_form = ExamFormForm(instance=initial_exam_form)

    if request.POST:
        exam_form_form = ExamFormForm(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,ExamForm)
            exam_form.save()

            for mc in initial_exam_form.get_modality_categories():
                new_mc = ModalityCategory(
                    exam_form = exam_form,
                    title = mc.title,
                    subtitle = mc.subtitle,
                    order = mc.order,
                    minimum_scans = mc.minimum_scans,
                    upload_disabled = mc.upload_disabled
                )
                new_mc.save()

                for mc_item in mc.get_items():
                    new_mi = ModalityItem(
                        name = mc_item.name,
                        category = new_mc,
                        type = mc_item.type,
                        order = mc_item.order,
                        minimum = mc_item.minimum,
                        maximum = mc_item.maximum
                    )
                    new_mi.save()

            messages.success(request,'Exam Form has been Duplicated')
            return HttpResponseRedirect(reverse('admin_exam_forms'))

    return render(request,'admin/exam_applications/duplicate-exam-form.html',{'initial_exam_form':initial_exam_form,'exam_form_form':exam_form_form})


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

    exam_form = get_object_or_404(ExamForm,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_exam_forms'))

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

    exam_form = get_object_or_404(ExamForm,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_exam_forms'))

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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    modality_categories = ModalityCategory.objects.filter(exam_form=exam_form)

    return render(request,'admin/exam_applications/modalities/modalities.html',{'exam_form':exam_form,'modality_categories':modality_categories})


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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    modality_category_form = ModalityCategoryForm()

    if request.POST:
        modality_category_form = ModalityCategoryForm(request.POST)

        if modality_category_form.is_valid():
            try:
                modality_category = modality_category_form.save(commit=False)
                modality_category.exam_form = exam_form
                modality_category.save()

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

            except:
                messages.error(request,'Could not create Modality Category')

    return render(request,'admin/exam_applications/modalities/add-modality-category.html',{'exam_form':exam_form,'modality_category_form':modality_category_form})


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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    modality_category = get_object_or_404(ModalityCategory,id=modality_cat_id)
    modality_category_form = ModalityCategoryForm(instance=modality_category)

    if request.POST:
        modality_category_form = ModalityCategoryForm(request.POST,instance=modality_category)

        if modality_category_form.is_valid():

            try:
                modality_category_form.save()
                messages.success(request,'Modality Category has been updated')
                return HttpResponseRedirect(reverse('admin_exam_forms_modalities',args=[exam_form.id]))
            except:
                messages.error(request,'Could not update Modality Category')

    return render(request,'admin/exam_applications/modalities/edit-modality-category.html',{'exam_form':exam_form,'modality_category':modality_category,'modality_category_form':modality_category_form})


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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    modality_category = get_object_or_404(ModalityCategory,id=modality_cat_id)

    try:
        modality_category.delete()
        messages.success(request,'Modality Category has been deleted')
    except:
        messages.error(request,'Could not delete Modality Category')

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


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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    modality_item_form = ModalityItemForm()

    modality_categories = ModalityCategory.objects.filter(exam_form=exam_form)
    modality_item_form.fields['category'].queryset = modality_categories

    if request.POST:
        modality_item_form = ModalityItemForm(request.POST)
        modality_item_form.fields['category'].queryset = modality_categories

        if modality_item_form.is_valid():
            try:
                modality_item = modality_item_form.save(commit=False)
                modality_item.save()

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

            except:
                messages.error(request,'Could not create Modality Item')

    return render(request,'admin/exam_applications/modalities/add-modality-item.html',{'exam_form':exam_form,'modality_item_form':modality_item_form})

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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    modality_item = get_object_or_404(ModalityItem,id=modality_item_id)
    modality_item_form = ModalityItemForm(instance=modality_item)

    modality_categories = ModalityCategory.objects.filter(exam_form=exam_form)
    modality_item_form.fields['category'].queryset = modality_categories

    if request.POST:
        modality_item_form = ModalityItemForm(request.POST,instance=modality_item)
        modality_item_form.fields['category'].queryset = modality_categories

        if modality_item_form.is_valid():
            try:
                modality_item = modality_item_form.save(commit=False)
                modality_item.save()

                messages.success(request,'Modality Item has been Updated')
                return HttpResponseRedirect(reverse('admin_exam_forms_modalities',args=[exam_form.id]))
            except:
                messages.error(request,'Could not Update Modality Item')

    return render(request,'admin/exam_applications/modalities/add-modality-item.html',{'exam_form':exam_form,'modality_item_form':modality_item_form,'modality_item':modality_item})

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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    modality_item = get_object_or_404(ModalityItem,id=modality_item_id)

    try:
        modality_item.delete()
        messages.success(request,'Modality Item has been deleted')
    except:
        messages.error(request,'Could not delete Modality Item')

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

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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    complete_applicants = ExamApplication.objects.filter(exam=exam_form, complete=True, paid=True).order_by('-completed_time')
    unpaid_applicants = ExamApplication.objects.filter(exam=exam_form, complete=True, paid=False)
    incomplete_applicants = ExamApplication.objects.filter(exam=exam_form, complete=False)

    return render(request,'admin/exam_applications/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(ExamForm,id=exam_id)
    complete_applicants = ExamApplication.objects.filter(exam=exam_form,complete=True,paid=True)

    fields = ['Submitted','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','Mailing Address 1','Mailing Address 2', 'Mailing Town','Mailing County','Mailing Postcode','Mailing Country','Modaility 1 Scans','Modality 2 Scans','Modality 3 Scans','Undergraduate University','Degree Title','Degree Class','Year Awarded','Postgraduate University','Degree Title','Year Awarded']

    for year in exam_form.get_years():
        fields.append('Physics %s' % (year) )

    for year in exam_form.get_years():
        fields.append('Vascular Tech %s' % (year) )

    for year in exam_form.get_years():
        fields.append('CPD Points %s' % (year) )

    if exam_form.type != 're-validation':
        for modality_category in exam_form.get_modality_categories():
            fields.append("%s Date Training Started" % (modality_category))
            for item in modality_category.get_compulsory_items():
                fields.append("%s Actual" % (item))
                fields.append("%s Eligible" % (item))
            for item in modality_category.get_optional_items():
                fields.append("%s Actual" % (item))
                fields.append("%s Eligible" % (item))
            fields.append("%s Total Eligible " % (modality_category))

        fields += ['Three Years Experience','Examiner Title','Examiner Name','Examiner Email','Examiner Unable Reason','Reference 1 Name','Address 1','Address 2','Town','County','Postcode','Country','Email','Telephone','Reference 2 Name','Address 1','Address 2','Town','County','Postcode','Country','Email','Telephone','Other References']

    else:
        fields += ['Examiner Title','Examiner Name','Examiner Email','Examiner Unable Reason','Reference 1 Name','Address 1','Address 2','Town','County','Postcode','Country','Email','Telephone','Reference 2 Name','Address 1','Address 2','Town','County','Postcode','Country','Email','Telephone','Other References']

    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:
        fields = [applicant.completed_time,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,applicant.modality_1_scans,applicant.modality_2_scans,applicant.modality_3_scans,applicant.university_name,applicant.degree_title,applicant.degree_class,applicant.year_awarded,applicant.pg_university_name,applicant.pg_degree_title,applicant.pg_year_awarded,applicant.phi_y1,applicant.phi_y2,applicant.phi_y3,applicant.phi_y4,applicant.phi_y5,applicant.phi_y6,applicant.vt_y1,applicant.vt_y2,applicant.vt_y3,applicant.vt_y4,applicant.vt_y5,applicant.vt_y6,applicant.cpd_y1,applicant.cpd_y2,applicant.cpd_y3,applicant.cpd_y4,applicant.cpd_y5,applicant.cpd_y6]

        if exam_form.type != 're-validation':
            for modality_category in exam_form.get_modality_categories():
                sub_category = applicant.get_app_category(modality_category)
                if sub_category:
                    fields.append(sub_category.training_began.strftime("%m/%Y"))
                else:
                    fields.append('')
                for item in modality_category.get_compulsory_items():
                    sub_item = applicant.get_app_item(item)
                    if sub_item:
                        if sub_item.complete:
                            fields.append('Yes')
                        else:
                            fields.append('No')
                    else:
                        fields.append('')
                        fields.append('')
                for item in modality_category.get_optional_items():
                    sub_item = applicant.get_app_item(item)
                    if sub_item:
                        if sub_item.complete:
                            fields.append('Yes')
                        else:
                            fields.append('No')
                    else:
                        fields.append('')
                        fields.append('')
                if sub_category:
                    fields.append(sub_category.total_scans)
                else:
                    fields.append('')

            fields += [applicant.three_years_experience,applicant.examiner_title,"%s %s" % (applicant.examiner_first_name, applicant.examiner_surname),applicant.examiner_email,applicant.examiner_unable_reason]
        else:
            fields += [applicant.examiner_title,"%s %s" % (applicant.examiner_first_name, applicant.examiner_surname),applicant.examiner_email,applicant.examiner_unable_reason]

        for reference in applicant.get_references():
            fields += [reference.name,reference.address_1,reference.address_2,reference.town,reference.county,reference.postcode,reference.country,reference.email,reference.telephone]

        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(ExamForm,id=exam_id)
    application = get_object_or_404(ExamApplication,id=application_id)

    return render(request,'admin/exam_applications/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(ExamForm,id=exam_id)
    application = get_object_or_404(ExamApplication,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_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(ExamForm,id=exam_id)
    application = get_object_or_404(ExamApplication,id=application_id)

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

    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_exam_applicants',args=[exam_form.id]))


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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    application = get_object_or_404(ExamApplication,id=application_id)

    if application.degree_certificate:
        return serve_file(request,application.degree_certificate,save_as=True)
    else:
        messages.error(request,'Sorry this application does not have a Degree Certificate')

    return HttpResponseRedirect(reverse('admin_exam_view_application',args=[exam_id,application_id]))

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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    application = get_object_or_404(ExamApplication,id=application_id)

    if application.non_degree_evidence:
        return serve_file(request,application.non_degree_evidence,save_as=True)
    else:
        messages.error(request,'Sorry this application does not have Non Degree Evidence')

    return HttpResponseRedirect(reverse('admin_exam_view_application',args=[exam_id,application_id]))

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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    application = get_object_or_404(ExamApplication,id=application_id)

    if application.exam_results_letter:
        return serve_file(request,application.exam_results_letter,save_as=True)
    else:
        messages.error(request,'Sorry this application does not have an Exam Results Letter')

    return HttpResponseRedirect(reverse('admin_exam_view_application',args=[exam_id,application_id]))

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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    application = get_object_or_404(ExamApplication,id=application_id)

    if application.reference_upload:
        return serve_file(request,application.reference_upload,save_as=True)
    else:
        messages.error(request,'Sorry this application does not have a Reference Upload')

    return HttpResponseRedirect(reverse('admin_exam_view_application',args=[exam_id,application_id]))

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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    application = get_object_or_404(ExamApplication,id=application_id)
    sub_category = get_object_or_404(ExamApplicationModalityCategory, id=subcategory_id)

    if sub_category.scans_file:
        return serve_file(request,sub_category.scans_file,save_as=True)
    else:
        messages.error(request,'Sorry this application does not have an Scans file for this Modality')

    return HttpResponseRedirect(reverse('admin_exam_view_application',args=[exam_id,application_id]))


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

    exam_form = get_object_or_404(ExamForm,id=exam_id)
    application = get_object_or_404(ExamApplication,id=application_id)

    subcategories = ExamApplicationModalityCategory.objects.filter(exam_application=application)
    for sub_category in subcategories:
        sub_category.scans_file = ''
        sub_category.save()

    messages.success(request, 'Scan Files Cleared')

    return HttpResponseRedirect(reverse('admin_exam_view_application',args=[exam_id,application_id]))
