#Django core bits
from django.shortcuts import render, render_to_response, get_object_or_404
from django.template import RequestContext, loader, Context
from django.contrib.auth.decorators import login_required, permission_required
from django.http import HttpResponseRedirect, Http404, HttpResponse
from django.core.urlresolvers import reverse

from datetime import datetime,date,time
from dateutil.relativedelta import *

#Forms
from modules.members.adminforms import *

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

#Others
import random,csv,string

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

import pdfcrowd

def renew_direct_debits(request,direct_debits):

    members_renewed = []

    for direct_debit in direct_debits:
        if direct_debit.member:

            member = direct_debit.member

            if member.member_status == 'current':

                member_type = member.member_type
                total = member_type.renewal_fee - member_type.dd_discount

                start_date = member.expiry_date+relativedelta(days=1)

                if member_type.subscription_length == '3-months':
                    end_date = member.expiry_date+relativedelta(months=+3)
                elif member_type.subscription_length == '6-months':
                    end_date = member.expiry_date+relativedelta(months=+6)
                else:
                    end_date = member.expiry_date+relativedelta(months=+12)

                subscription_name = '%s Membership Subscription (%s)' % (member_type.name,start_date.strftime('%B %Y'))
                invoice_to_name = '%s %s %s' % (member.get_title_display(),member.given_name,member.surname)

                member_subscription = MemberSubscription(
                    member=member,
                    member_type = member_type,
                    subscription=subscription_name,
                    amount=member_type.renewal_fee,
                    discount=member_type.dd_discount,
                    total= total,
                    invoice_to=invoice_to_name,
                    status='pending',
                    start_date=start_date,
                    expiry_date=end_date,
                    invoice_created=date.today())
                member_subscription.save()

                member.expiry_date = end_date
                member.save()

                receipt_name = '%s Membership Subscription (%s)' % (settings.WEBSITE_NAME,start_date.strftime('%B %Y'))
                receipt = Receipt(member=member,name=receipt_name,start_date=member_subscription.start_date,amount_paid=total,payment_type='Direct Debit',member_subscription=member_subscription)
                receipt.save()

                try:
                    # create an API client instance
                    client = pdfcrowd.Client("calmdigital", "dc33e7c4525620565185d0a00d90b8f0")
                    client.setPageMargins('50','50','0','50')
                    client.setFooterHtml('<p style="font-size:12px; text-align:center;">The Society for Vascular Technology of Great Britain and Ireland %s</p>' % (date.today().strftime('%d/%m/%Y')))
                    # convert an HTML string and save the result to a file
                    output_file = open(os.path.join(settings.MEDIA_ROOT, 'members/receipts/membership_renewal_%s.pdf' % (receipt.id)), 'wb')
                    html = loader.render_to_string('members/receipts/view-receipt-pdf.html',{'receipt':receipt},context_instance=RequestContext(request))
                    client.convertHtml(html,output_file)
                    output_file.close()
                except:
                    pass

                receipt.file = 'members/receipts/membership_renewal_%s.pdf' % (receipt.id)
                receipt.save()

                #create certificate pdf
                certificate = Certificate(member=member,start_date=member_subscription.start_date,end_date=member_subscription.expiry_date)
                certificate.save()

                try:
                    client = pdfcrowd.Client("calmdigital", "dc33e7c4525620565185d0a00d90b8f0")
                    client.setPageMargins('50','50','0','50')
                    output_file = open(os.path.join(settings.MEDIA_ROOT, 'members/certificates/membership_certificate_%s.pdf' % (certificate.id)), 'wb')
                    html = render_to_string('members/certificates/view-cert-pdf.html',{'certificate':certificate},context_instance=RequestContext(request))
                    client.convertHtml(html,output_file)
                    output_file.close()
                except:
                    pass

                certificate.file = 'members/certificates/membership_certificate_%s.pdf' % (certificate.id)
                certificate.save()

                renewal_confirmation.send(sender=None,request=request,member=member,subscription=member_subscription,method='Direct Debit',receipt=receipt,certificate=certificate,notify_admin=False)

                notification = UserActivity(member=member,type='account-notification',title='Membership Renewed',text='Your membership has been successfully renewed for 12 months.<br/>Visit <a href="%s">My Receipts</a> to view your receipt.' % (reverse('my_receipts')))
                notification.save()

                members_renewed.append(member)

    return members_renewed

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

    pending_direct_debits = MemberDirectDebit.objects.filter(status='pending').order_by('-created')
    current_direct_debits = MemberDirectDebit.objects.filter(status='current').order_by('-created','member__surname')

    return render(request,'admin/members/direct_debits/direct-debits.html',{'pending_direct_debits':pending_direct_debits,'current_direct_debits':current_direct_debits})


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

    archived_direct_debits = MemberDirectDebit.objects.filter(status='archived').order_by('member__surname')

    return render(request,'admin/members/direct_debits/archived-direct-debits.html',{'archived_direct_debits':archived_direct_debits})


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

    current_direct_debits = MemberDirectDebit.objects.filter(status='current').order_by('member__surname','-created')

    response = HttpResponse(content_type='text')
    response['Content-Disposition'] = "attachment; filename=direct_debits.txt"

    writer = csv.writer(response,quoting=csv.QUOTE_ALL)

    for direct_debit in current_direct_debits:

        if direct_debit.member.member_type:
            amount = direct_debit.member.member_type.renewal_fee - direct_debit.member.member_type.dd_discount
            amount = "%.0f" % (amount * 100)
        else:
            amount = 0

        if direct_debit.member:
            membership_number = str(direct_debit.member.membership_number).zfill(6)
        else:
            membership_number = '000000'

        writer.writerow([unicode(s).encode("utf-8") for s in (direct_debit.ac_name,direct_debit.ac_no,direct_debit.sort_code,amount,membership_number,direct_debit.submission)])

        #writer.writerow([unicode(s).encode("utf-8") for s in (membership_number,direct_debit.ac_name,amount,direct_debit.sort_code,direct_debit.ac_no,direct_debit.submission)])

    return response

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

    today = date.today()
    current_direct_debits = MemberDirectDebit.objects.filter(status='pending').order_by('member__surname','-created')

    response = HttpResponse(content_type='text')
    response['Content-Disposition'] = "attachment; filename=pending_direct_debits.txt"

    writer = csv.writer(response,quoting=csv.QUOTE_ALL)

    for direct_debit in current_direct_debits:

        if direct_debit.member.member_type:
            amount = direct_debit.member.member_type.renewal_fee - direct_debit.member.member_type.dd_discount
            amount = "%.0f" % (amount * 100)
        else:
            amount = 0

        if direct_debit.member:
            membership_number = str(direct_debit.member.membership_number).zfill(6)
        else:
            membership_number = '000000'

        writer.writerow([unicode(s).encode("utf-8") for s in (direct_debit.ac_name,direct_debit.ac_no,direct_debit.sort_code,amount,membership_number,direct_debit.submission)])

    return response

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

    direct_debits = MemberDirectDebit.objects.filter(status='current')
    members_renewed = renew_direct_debits(request,direct_debits)

    return render(request,'admin/members/direct_debits/members_renewed.html',{'members_renewed':members_renewed})


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

    today = date.today()
    two_months = today+relativedelta(months=+2)

    expiring_direct_debits = MemberDirectDebit.objects.filter(member__expiry_date__lte=two_months).order_by('member__expiry_date')

    return render(request,'admin/members/direct_debits/expiring-direct-debits.html',{'expiring_direct_debits':expiring_direct_debits})


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

    today = date.today()
    two_months = today+relativedelta(months=+2)
    expiring_direct_debits = MemberDirectDebit.objects.filter(member__expiry_date__lte=two_months).order_by('member__expiry_date')

    response = HttpResponse(content_type='text')
    response['Content-Disposition'] = "attachment; filename=expiring_direct_debits.txt"

    writer = csv.writer(response,quoting=csv.QUOTE_ALL)

    for direct_debit in expiring_direct_debits:

        if direct_debit.member.member_type:
            amount = direct_debit.member.member_type.renewal_fee - direct_debit.member.member_type.dd_discount
            amount = "%.0f" % (amount * 100)
        else:
            amount = 0

        if direct_debit.member:
            membership_number = str(direct_debit.member.membership_number).zfill(6)
        else:
            membership_number = '000000'

        writer.writerow([unicode(s).encode("utf-8") for s in (direct_debit.ac_name,direct_debit.ac_no,direct_debit.sort_code,amount,membership_number,direct_debit.submission)])

    return response

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

    today = date.today()
    two_months = today+relativedelta(months=+2)
    expiring_direct_debits = MemberDirectDebit.objects.filter(member__expiry_date__lte=two_months)

    members_renewed = renew_direct_debits(request,expiring_direct_debits)

    return render(request,'admin/members/direct_debits/members_renewed.html',{'members_renewed':members_renewed})


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

    direct_debit_form = AdminAddDirectDebitForm()

    if request.POST:

        direct_debit_form = AdminAddDirectDebitForm(request.POST)

        if direct_debit_form.is_valid():

            try:
                direct_debit = direct_debit_form.save(commit=False)

                existing_direct_debits = MemberDirectDebit.objects.filter(member=direct_debit.member,status='current')
                if existing_direct_debits:
                    messages.error(request,'Sorry, A Direct Debit alrrady exists for this member')
                else:
                    direct_debit_form.save()
                    messages.success(request,'Direct Debit has been saved')

                    return HttpResponseRedirect(reverse('admin_members_direct_debits'))
            except:
                messages.error(request,'Could not save direct debit')

    return render(request,'admin/members/direct_debits/add-direct-debit.html',{'direct_debit_form':direct_debit_form})

@permission_required('admin_users.can_access_members')
def view_direct_debit(request,id):

    direct_debit = get_object_or_404(MemberDirectDebit,id=id)

    return render(request,'admin/members/direct_debits/view-direct-debit.html',{'direct_debit':direct_debit})


@permission_required('admin_users.can_access_members')
def remove_old_direct_debit(request,id):

    direct_debit = get_object_or_404(MemberDirectDebit,id=id)

    try:
        direct_debit.old_sort_code = ''
        direct_debit.old_ac_name = ''
        direct_debit.old_ac_no = ''
        direct_debit.save()

        messages.success(request,'Details Marked as Current and old removed')

    except:

        messages.error(request,'Could not mark details as current')

    return HttpResponseRedirect(reverse('admin_members_view_direct_debit',args=[direct_debit.id]))

@permission_required('admin_users.can_access_members')
def edit_direct_debit(request,id):

    direct_debit = get_object_or_404(MemberDirectDebit,id=id)
    direct_debit_form = AdminEditDirectDebitForm(instance=direct_debit)

    if request.POST:

        direct_debit_form = AdminEditDirectDebitForm(request.POST,instance=direct_debit)

        if direct_debit_form.is_valid():

            try:
                direct_debit = direct_debit_form.save()
                messages.success(request,'Direct Debit has been saved')

                return HttpResponseRedirect(reverse('admin_members_direct_debits'))

            except:
                messages.error(request,'Could not save direct debit')

    return render(request,'admin/members/direct_debits/edit-direct-debit.html',{'direct_debit':direct_debit,'direct_debit_form':direct_debit_form})

@permission_required('admin_users.can_access_members')
def delete_direct_debit(request,id):

    direct_debit = get_object_or_404(MemberDirectDebit,id=id)

    try:
        direct_debit.delete()

        messages.success(request,'Direct Debit Deleted')

    except:
        messages.error(request,'Could not delete Direct Debit')

    return HttpResponseRedirect(reverse('admin_members_archived_direct_debits'))

@permission_required('admin_users.can_access_members')
def activate_direct_debit(request,id):

    direct_debit = get_object_or_404(MemberDirectDebit,id=id)

    try:
        direct_debit.status = 'current'
        direct_debit.save()

        messages.success(request,'Direct debit is activated for <a href="%s">%s</a>' % (reverse('view_member',args=[direct_debit.member.id]),direct_debit.member))

    except:
        messages.error(request,'Could not mark Direct Debit activated for %s' % (member))

    return HttpResponseRedirect(reverse('admin_members_archived_direct_debits'))

@permission_required('admin_users.can_access_members')
def confirm_direct_debit(request,id):

    direct_debit = get_object_or_404(MemberDirectDebit,id=id)

    try:
        direct_debit.status = 'current'
        direct_debit.save()

        messages.success(request,'Direct debit is confirmed for <a href="%s">%s</a>' % (reverse('view_member',args=[direct_debit.member.id]),direct_debit.member))

    except:
        messages.error(request,'Could not mark Direct Debit confirmed for %s' % (member))

    return HttpResponseRedirect(reverse('admin_members_view_direct_debit',args=[direct_debit.id]))


@permission_required('admin_users.can_access_members')
def archive_direct_debit(request,id):

    direct_debit = get_object_or_404(MemberDirectDebit,id=id)

    try:
        direct_debit.status = 'archived'
        direct_debit.save()

        messages.success(request,'Direct debit is archived for <a href="%s">%s</a>' % (reverse('view_member',args=[direct_debit.member.id]),direct_debit.member))

    except:
        messages.error(request,'Could not mark Direct Debit archived for %s' % (direct_debit.member))

    return HttpResponseRedirect(reverse('admin_members_direct_debits'))


@permission_required('admin_users.can_access_members')
def mark_existing_direct_debit(request,id):

    direct_debit = get_object_or_404(MemberDirectDebit,id=id)

    try:
        direct_debit.submission = '17'
        direct_debit.save()

        messages.success(request,'Direct debit has been marked as Existing for <a href="%s">%s</a>' % (reverse('view_member',args=[direct_debit.member.id]),direct_debit.member))

    except:
        messages.error(request,'Could not mark Direct Debit as Existing for %s' % (direct_debit.member))

    return HttpResponseRedirect(reverse('admin_members_direct_debits'))


@permission_required('admin_users.can_access_members')
def process_direct_debit(request,id):

    direct_debit = get_object_or_404(MemberDirectDebit,id=id)

    members_renewed = renew_direct_debits(request,[direct_debit])
    if members_renewed:
        member = members_renewed[0]

        messages.success(request,'Member %s Renewed Successfully <a href="%s">View Profile</a>' % (member,reverse('view_member',args=[direct_debit.member.id])))

    else:
        messages.error(request,'Could not Renew Member')

    return HttpResponseRedirect(reverse('admin_members_expiring_direct_debits'))
