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 django.db.models import Q

from modules.core.functions import *

#Forms
from forms import *

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

import emails

@permission_required('admin_users.can_access_cpd')
def cpd_options(request):

    cpd_categories = CPDCategory.objects.all()

    return render(request,'admin/cpd/options/cpd-options.html',{'cpd_categories':cpd_categories})


@permission_required('admin_users.can_access_cpd')
def add_cpd_category(request):

    cpd_category_form = CPDCategoryForm()

    if request.POST:
        cpd_category_form = CPDCategoryForm(request.POST)

        try:
            cpd_category_form.save()
            messages.success(request,'CPD Category has been created')

            return HttpResponseRedirect(reverse('admin_cpd_options'))

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

    return render(request,'admin/cpd/options/add-cpd-category.html',{'cpd_category_form':cpd_category_form})


@permission_required('admin_users.can_access_cpd')
def edit_cpd_category(request,category_id):

    cpd_category = get_object_or_404(CPDCategory,id=category_id)
    cpd_category_form = CPDCategoryForm(instance=cpd_category)

    if request.POST:
        cpd_category_form = CPDCategoryForm(request.POST,instance=cpd_category)

        if cpd_category_form.is_valid():

            try:
                cpd_category_form.save()
                messages.success(request,'CPD Category has been updated')

                return HttpResponseRedirect(reverse('admin_cpd_options'))

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

    return render(request,'admin/cpd/options/edit-cpd-category.html',{'cpd_category':cpd_category,'cpd_category_form':cpd_category_form})


@permission_required('admin_users.can_access_cpd')
def delete_cpd_category(request,category_id):

    cpd_category = get_object_or_404(CPDCategory,id=category_id)
    try:
        cpd_category.delete()
        messages.success(request,'CPD Category has been deleted')
    except:
        messages.error(request,'Could not delete CPD Category')

    return HttpResponseRedirect(reverse('admin_cpd_options'))

@permission_required('admin_users.can_access_cpd')
def add_cpd_item(request):

    cpd_item_form = CPDItemForm()

    if request.POST:
        cpd_item_form = CPDItemForm(request.POST)

        try:
            cpd_item_form.save()
            messages.success(request,'CPD Category has been created')

            return HttpResponseRedirect(reverse('admin_cpd_options'))

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

    return render(request,'admin/cpd/options/add-cpd-item.html',{'cpd_item_form':cpd_item_form})


@permission_required('admin_users.can_access_cpd')
def edit_cpd_item(request,item_id):

    cpd_item = get_object_or_404(CPDItem,id=item_id)
    cpd_item_form = CPDItemForm(instance=cpd_item)

    if request.POST:
        cpd_item_form = CPDItemForm(request.POST,instance=cpd_item)

        if cpd_item_form.is_valid():

            try:
                cpd_item_form.save()
                messages.success(request,'CPD Category has been updated')

                return HttpResponseRedirect(reverse('admin_cpd_options'))

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

    return render(request,'admin/cpd/options/edit-cpd-item.html',{'cpd_item':cpd_item,'cpd_item_form':cpd_item_form})


@permission_required('admin_users.can_access_cpd')
def delete_cpd_item(request,item_id):

    cpd_item = get_object_or_404(CPDItem,id=item_id)
    try:
        cpd_item.delete()
        messages.success(request,'CPD Category has been deleted')
    except:
        messages.error(request,'Could not delete CPD Category')

    return HttpResponseRedirect(reverse('admin_cpd_options'))

@permission_required('admin_users.can_access_cpd')
def cpd_submissions(request):

    recent_cpd_submissions = CPDSubmission.objects.filter(approved=True).order_by('-created')[:10]
    pending_cpd_submissions = CPDSubmission.objects.filter(approved=False).order_by('-created')

    letters = map(chr, range(97, 123))
    member = Member()
    final_letters = []

    for letter in letters:
        status = member.get_letter_active(letter)
        if status:
            final_letters.append(letter)

    today = date.today()
    if today.month > 8:
        future_year = today.year + 1
        current_year = today.year
    else:
        future_year = today.year
        current_year = today.year - 1


    """all_submissions = CPDSubmission.objects.all()

    for submission in all_submissions:
        if submission.date.month >= 9:
            start_date = date(submission.date.year,9,1)
            end_date = date(submission.date.year + 1,8,31)
        else:
            start_date = date(submission.date.year - 1,9,1)
            end_date = date(submission.date.year,8,31)

        try:
            year = CPDSubmissionYear.objects.get(member=submission.member,start_date=start_date,end_date=end_date)
        except CPDSubmissionYear.DoesNotExist:
            year = CPDSubmissionYear(member=submission.member,start_date=start_date,end_date=end_date)
        year.save()"""

    return render(request,'admin/cpd/submissions/cpd-submissions.html',{'recent_cpd_submissions':recent_cpd_submissions,'pending_cpd_submissions':pending_cpd_submissions,'letters':letters,'final_letters':final_letters,'current_year':current_year,'future_year':future_year})

@permission_required('admin_users.can_access_cpd')
def cpd_submissions_download(request,future=False):

    import csv

    members = Member.objects.filter(approved=True,member_status='current',user_type='member')

    fields = ['Member Id', 'Name','Email Address', 'Status','Points Gained', 'AVS Points Gained']

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

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

    for member in members:

        if future:
            #current
            if member.get_avs():
                avs = member.get_future_avs_points()
            else:
                avs = 'Not AVS'
            writer.writerow([unicode(s).encode("utf-8") for s in [member.membership_number,member,member.user.email,member.get_future_cpd_status(),member.get_future_cpd_points(),avs]])
        else:
            #current
            if member.get_avs():
                avs = member.get_current_avs_points()
            else:
                avs = 'Not AVS'
            writer.writerow([unicode(s).encode("utf-8") for s in [member.membership_number,member,member.user.email,member.get_current_cpd_status(),member.get_current_cpd_points(),avs]])

    return response


@permission_required('admin_users.can_access_cpd')
def alpha_members(request,letter):

    letters = map(chr, range(97, 123))
    member = Member()
    final_letters = []

    for prim_letter in letters:
        status = member.get_letter_active(prim_letter)
        if status:
            final_letters.append(prim_letter)

    members = Member.objects.filter(user__last_name__istartswith=letter,user_type='member',approved=True,member_status='current').order_by('user__last_name')

    return render(request,'admin/cpd/submissions/member_list_alpha.html',{'letters':letters,'final_letters':final_letters,'members':members,'letter':letter,})


@permission_required('admin_users.can_access_members')
def search_name(request):

    letters = map(chr, range(97, 123))
    member = Member()
    final_letters = []

    for letter in letters:
        status = member.get_letter_active(letter)
        if status:
            final_letters.append(letter)

    if request.POST:
        if request.POST.get('member_name'):

            member_name = request.POST['member_name']
            members = Member.objects.filter(Q(given_name__icontains=request.POST['member_name']) | Q(surname__icontains=request.POST['member_name']),user_type='member',approved=True).order_by('surname')

            return render(request,'admin/cpd/submissions/search-name.html',{'letters':letters,'final_letters':final_letters,'member_name':member_name,'members':members})
        else:
            messages.error(request,'Could not search for members')
    else:
        messages.error(request,'Could not search for members')

    return HttpResponseRedirect(reverse('admin_cpd_submissions'))


@permission_required('admin_users.can_access_cpd')
def view_member(request,member_id):

    member = get_object_or_404(Member,id=member_id)
    pending_submissions = CPDSubmission.objects.filter(member=member,approved=False).order_by('-date')
    cpd_submissions = CPDSubmission.objects.filter(member=member,approved=True).order_by('-date')
    cpd_years = CPDSubmissionYear.objects.filter(member=member).order_by('-end_date')

    return render(request,'admin/cpd/submissions/view-member.html',{'member':member,'pending_submissions':pending_submissions,'cpd_submissions':cpd_submissions,'cpd_years':cpd_years})

@permission_required('admin_users.can_access_cpd')
def add_submission(request):

    submission_form = AdminAddCPDSubmissionForm()
    reflection_form = AdminCPDReflectionForm()
    file_form = CPDSubmissionEvidenceForm(prefix='file_1')
    file_forms = [file_form]

    if request.POST:
        submission_form = AdminAddCPDSubmissionForm(request.POST,request.FILES)
        reflection_form = AdminCPDReflectionForm(request.POST)

        if submission_form.is_valid() and reflection_form.is_valid():
            submission = submission_form.save(commit=False)
            submission.approved = True
            submission.save()

            reflection_form = AdminCPDReflectionForm(request.POST, instance=submission)
            reflection_form.save()

            posted_files = request.POST.getlist('files')
            file_forms = []
            file_order = 1

            for posted_file in posted_files:

                if request.FILES.get('file_%s-file' % posted_file):
                    #new file
                    file_form = CPDSubmissionEvidenceForm(request.POST,request.FILES,prefix='file_%s' % (posted_file))
                    submitted_file = file_form.save(commit=False)
                    submitted_file.submission = submission
                    submitted_file.order = file_order
                    submitted_file.save()

                    new_file_form = CPDSubmissionEvidenceForm(prefix='file_%s' % (posted_file))
                    file_forms.append(new_file_form)
                file_order = file_order + 1

                messages.success(request,'Submission Created')

            if submission.date.month >= 9:
                start_date = date(submission.date.year,9,1)
                end_date = date(submission.date.year + 1,8,31)
            else:
                start_date = date(submission.date.year - 1,9,1)
                end_date = date(submission.date.year,8,31)

            try:
                year = CPDSubmissionYear.objects.get(member=submission.member,start_date=start_date,end_date=end_date)
            except CPDSubmissionYear.DoesNotExist:
                year = CPDSubmissionYear(member=submission.member,start_date=start_date,end_date=end_date)
                year.save()

            return HttpResponseRedirect(reverse('admin_cpd_view_member',args=[submission.member.id]))

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

    return render(request,'admin/cpd/submissions/add-submission.html',{'submission_form':submission_form, 'reflection_form':reflection_form, 'file_forms':file_forms})

@permission_required('admin_users.can_access_cpd')
def edit_submission(request,submission_id):

    submission = get_object_or_404(CPDSubmission,id=submission_id)
    submission_form = AdminCPDSubmissionForm(instance=submission)
    reflection_form = AdminCPDReflectionForm(instance=submission)

    submission_evidence = submission.get_evidence()
    file_forms = []
    for evidence in submission_evidence:
        file_form = CPDSubmissionEvidenceForm(instance=evidence,prefix='file_%s' % (evidence.order))
        file_forms.append(file_form)

    if request.POST:
        submission_form = AdminCPDSubmissionForm(request.POST,request.FILES,instance=submission)
        reflection_form = AdminCPDReflectionForm(request.POST, instance=submission)

        if submission_form.is_valid():
            submission_form.save()
            reflection_form.save()

            posted_files = request.POST.getlist('files')
            file_forms = []
            current_files = []
            file_order = 1
            for posted_file in posted_files:

                try:
                    #existing_file
                    existing_file = CPDSubmissionEvidence.objects.get(submission=submission,order=posted_file)
                    file_form = CPDSubmissionEvidenceForm(request.POST,request.FILES,instance=existing_file,prefix='file_%s' % (posted_file))
                    existing_file = file_form.save(commit=False)
                    existing_file.order = file_order
                    existing_file.save()

                    current_files.append(existing_file)

                except CPDSubmissionEvidence.DoesNotExist:

                    if request.FILES.get('file_%s-file' % posted_file):
                        #new file
                        file_form = CPDSubmissionEvidenceForm(request.POST,request.FILES,prefix='file_%s' % (posted_file))
                        submitted_file = file_form.save(commit=False)
                        submitted_file.submission = submission
                        submitted_file.order = file_order
                        submitted_file.save()

                file_order = file_order + 1

            #remove not required files
            for file in submission_evidence:
                if file not in current_files:
                    file.delete()

            messages.success(request,'Submission Updated')

            return HttpResponseRedirect(reverse('admin_cpd_view_member',args=[submission.member.id]))

    return render(request,'admin/cpd/submissions/edit-submission.html',{'submission':submission,'member':submission.member,'submission_form':submission_form,'reflection_form':reflection_form, 'file_forms':file_forms})


@permission_required('admin_users.can_access_abstracts')
def view_reflection(request, submission_id):

    submission = get_object_or_404(CPDSubmission,id=submission_id)

    return render(request,'admin/cpd/submissions/view-reflection.html',{'submission':submission })

@permission_required('admin_users.can_access_cpd')
def delete_submission(request,submission_id):

    submission = get_object_or_404(CPDSubmission,id=submission_id)

    try:
        submission.delete()
        messages.success(request,'CPD Submission Deleted')
    except:
         messages.error(request,'Could not delete CPD Submission')

    return HttpResponseRedirect(reverse('admin_cpd_view_member',args=[submission.member.id]))

@permission_required('admin_users.can_access_cpd')
def approve_submission(request,submission_id):

    submission = get_object_or_404(CPDSubmission,id=submission_id,approved=False)

    approval_form = CPDSubmissionApprovalForm(instance=submission)

    if request.POST:
        approval_form = CPDSubmissionApprovalForm(request.POST,instance=submission)

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

                submission.approved = True
                submission.save()

                #email goes here
                emails.cpd_record_approved(request,submission)
                messages.success(request,'Submission has been approved')

            except:
                submission.approved = False
                submission.save()

            return HttpResponseRedirect(reverse('admin_cpd_view_member',args=[submission.member.id]))

        messages.error(request,'Could not approve submission')

    return render(request,'admin/cpd/submissions/approve-submission.html',{'submission':submission,'member':submission.member,'approval_form':approval_form})


@permission_required('admun_users.can_access_cpd')
def reject_submission(request,submission_id):

    submission = get_object_or_404(CPDSubmission,id=submission_id,approved=False)

    try:
        emails.cpd_record_rejected(request,submission)
        submission.delete()

        messages.success(request,'Submission has been rejected')
    except:
        messages.error(request,'Could not reject submission')

    return HttpResponseRedirect(reverse('admin_cpd_view_member',args=[submission.member.id]))

@permission_required('admin_users.can_access_cpd')
def download_evidence(request,submission_id):
    from filetransfers.api import serve_file

    submission = get_object_or_404(CPDSubmission,id=submission_id)

    if submission.evidence:
        return serve_file(request,submission.evidence,save_as=True)
    else:
        raise Http404

@permission_required('admin_users.can_access_cpd')
def download_submission_evidence(request,evidence_id):
    from filetransfers.api import serve_file

    evidence = get_object_or_404(CPDSubmissionEvidence,id=evidence_id)

    if evidence.file:
        return serve_file(request,evidence.file,save_as=True)
    else:
        raise Http404

def process_submissions(request,key):

    import pdfcrowd

    if key != "dhsuhdushfuhwuriehu8":
        raise Http404

    today = date.today()

    cpd_members = []
    ne_members = []

    members = Member.objects.filter(approved=True,member_status='current',user_type='member')

    for member in members:
        if member.user.email == 'daniel@capabilitycloud.co.uk':
            status = member.get_current_cpd_status()

            if status == 'ok':

                year = member.get_latest_cpd_year()
                #return render(request,'members/cpd/cpd-certificate.html',{'cpd_year':year,'today':today,'member':member})

                #try:
                client = pdfcrowd.Client("calmdigital", "dc33e7c4525620565185d0a00d90b8f0")
                client.setPageMargins('50','50','50','50')
                output_file = open(os.path.join(settings.MEDIA_ROOT, 'cpd/certificates/cpd_certificate_%s.pdf' % (year.id)), 'wb')
                html = loader.render_to_string('members/cpd/cpd-certificate.html',{'cpd_year':year,'today':today,'member':member})
                client.convertHtml(html,output_file)
                output_file.close()
                #except:
                #    pass

                year.certificate = 'cpd/certificates/cpd_certificate_%s.pdf' % (year.id)
                year.save()

                emails.cpd_certificate_generated(request,year)

                cpd_members.append({'member':member})
            else:
                ne_members.append({'member':member})

    content = loader.render_to_string('admin/cpd/cpd-report.html',{'cpd_members':cpd_members,'ne_members':ne_members})
    from modules.notifications.models import send_mail
    send_mail('cpd-report','SVTGBI - CPD Report',content,'admin@svtgbi.org.uk',['admin@svtgbi.org.uk','daniel@capabilitycloud.co.uk'])

    return render(request,'admin/cpd/cpd-report.html',{'cpd_members':cpd_members,'ne_members':ne_members})
