# Django core bits
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.template.loader import render_to_string
from django.core.urlresolvers import reverse
from django.contrib import messages
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings

from modules.core.decorators import current_members_only
from modules.core.functions import slugify_unique, random_string_unique

# Forms
from forms import AddAdvertForm

# Models
from models import JobSettings, JobCategory, Job
from modules.payments.models import Payment
from modules.members.models import Member, Receipt

from emails import job_advert_paid, job_advert_created

from datetime import date

import pdfcrowd
import os


def jobs(request):

    job_settings = JobSettings.get_solo()

    categories = JobCategory.objects.all()

    today = date.today()
    latest_jobs = Job.objects.filter(published=True, closing_date__gte=today).order_by('closing_date')

    return render(request, 'public/jobs/jobs.html', {'job_settings': job_settings, 'categories': categories, 'jobs': latest_jobs})


def category(request, category_slug):

    categories = JobCategory.objects.all()

    today = date.today()
    category = get_object_or_404(JobCategory, slug=category_slug)
    jobs = Job.objects.filter(categories=category, published=True, closing_date__gte=today).order_by('closing_date')

    return render(request, 'public/jobs/category.html', {'categories': categories, 'current_category': category, 'jobs': jobs})


def job(request, job_slug):

    job = get_object_or_404(Job, slug=job_slug)

    categories = JobCategory.objects.all()

    return render(request, 'public/jobs/job.html', {'job': job, 'categories': categories})


@current_members_only
def add_advert(request):

    member = get_object_or_404(Member, user=request.user)
    add_advert_form = AddAdvertForm()
    job_settings = JobSettings.get_solo()

    categories = JobCategory.objects.all()

    if request.POST:
        add_advert_form = AddAdvertForm(request.POST)

        if add_advert_form.is_valid():
            try:
                advert = add_advert_form.save(commit=False)
                advert.slug = slugify_unique(advert.title, Job)
                advert.member = member
                advert.save()
                add_advert_form.save_m2m()

                if advert.get_total() > 0:
                    advert.unique_key = random_string_unique(100, Job, 'unique_key')
                    advert.save()
                    request.session['advert_key'] = advert.unique_key
                    return HttpResponseRedirect(reverse('jobs_add_advert_payment'))
                else:
                    advert.complete = True
                    advert.save()
                    job_advert_created(request, advert)
                    return HttpResponseRedirect(reverse('jobs_add_advert_complete'))

            except Exception:
                messages.error(request, 'Sorry, could not create your advert')

    return render(request, 'public/jobs/add-advert.html', {'job_settings': job_settings, 'categories': categories, 'add_advert_form': add_advert_form})


@current_members_only
def add_advert_payment(request):

    member = get_object_or_404(Member, user=request.user)

    if request.session.get('advert_key', False):
        advert = get_object_or_404(Job, unique_key=request.session['advert_key'])

        if advert.complete:
            del request.session['advert_key']
            messages.error(request, 'You have already completed payment.')
            return HttpResponseRedirect(reverse('jobs_add_advert'))

    else:
        return HttpResponseRedirect(reverse('jobs_add_advert'))

    cost = advert.get_total()

    payment = Payment(member=member, type='job-advert', job_advert=advert)
    payment.save()

    if settings.DEVELOPMENT:
        payment.invoice = "Job_Advert_%sD" % (payment.id)
    else:
        payment.invoice = "Job_Advert_%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('jobs_add_advert_payment_process'))
    string = "%s:%s:%s:GBP:%s:%s" % (secret_key, installation_id, cost, payment.invoice, redirect_url)
    import hashlib
    encrypted_string = hashlib.md5(string).hexdigest()

    return render(request, 'public/jobs/payment.html', {'advert': advert, 'total_cost': cost, 'payment': payment, 'redirect_url': redirect_url, 'encrypted_string': encrypted_string})


@csrf_exempt
def add_advert_payment_process(request):

    if not request.POST:
        raise Http404

    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 = []

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

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

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

            if payment.status == 'pending':

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

                advert = payment.job_advert

                advert.complete = True
                advert.paid = True
                advert.price_paid = payment.amount
                advert.save()

                receipt_name = 'Job Advert'
                receipt = Receipt(member=advert.member, job_advert=advert, type='job-advert', name=receipt_name, amount_paid=payment.amount, payment_type='Credit Card')
                receipt.unique_key = random_string_unique(20, Receipt, 'unique_key')
                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/job_advert_%s.pdf' % (receipt.id)), 'wb')

                html = render_to_string('members/receipts/view-receipt-pdf.html', {'receipt': receipt})
                client.convertHtml(html, output_file)

                output_file.close()

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

                # except:
                #    pass

                job_advert_paid(request, advert, receipt)

            next = "%s%s" % (settings.URL, reverse('jobs_add_advert_payment_complete'))
        else:
            payment.status = 'rejected'
            payment.save()
            next = "%s%s" % (settings.URL, reverse('jobs_add_advert_payment_failure'))
    else:
        payment.status = 'rejected'
        payment.save()
        next = "%s%s" % (settings.URL, reverse('jobs_add_advert_payment_failure'))

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


@csrf_exempt
def add_advert_payment_complete(request):

    job_settings = JobSettings.get_solo()

    if request.session.get('advert_key', False):
        del request.session['advert_key']

    return render(request, 'public/jobs/add-advert-complete.html', {'job_settings': job_settings})


def add_advert_payment_failure(request):

    messages.error(request, 'Sorry, your payment could not be taken at this time. If you wish to retry your payment, please click below.')

    return HttpResponseRedirect(reverse('jobs_add_advert_payment'))


@current_members_only
def add_advert_complete(request):

    job_settings = JobSettings.get_solo()

    categories = JobCategory.objects.all()

    return render(request, 'public/jobs/add-advert-complete.html', {'job_settings': job_settings, 'categories': categories})
