#Django core bits
from django.shortcuts import 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.db.models import Q
from django.contrib.sites.models import Site
from django.conf import settings
from django.http import HttpResponseRedirect, Http404, HttpResponse
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User, Group
from django.contrib import messages
from django.template.defaultfilters import slugify
from datetime import datetime, date, time
import csv

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

#Forms
from forms import *

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

import emails

def can_view(member,abstract_request):

    allowed = True

    if abstract_request.member_types_allowed.all():
        if member:
            if not member.member_type in abstract_request.member_types_allowed.all():
                allowed = False
        else:
            allowed = False

    if abstract_request.member_groups_allowed.all():
        if member:
            in_groups = False
            for group in abstract_request.member_groups_allowed.all():
                if member in group.members.all():
                    in_groups = True

            if not in_groups:
                allowed = False
        else:
            allowed = False

    return allowed


def submission(request,abstract_request_slug):

    abstract_request = get_object_or_404(AbstractRequest,slug=abstract_request_slug)

    try:
        member = Member.objects.get(user=request.user)

        if member.member_status == 'lapsed':
            messages.warning(request,'Sorry your membership has lapsed, you will need to renew your membership to be able to access this submission form.')
            return HttpResponseRedirect(reverse('account_renew'))

    except:
        member = False

    if not abstract_request.enabled:
        return render_to_response('public/abstracts/disabled.html',{'abstract_request':abstract_request},context_instance=RequestContext(request))

    if not can_view(member,abstract_request):
        return render_to_response('public/abstracts/content-denied.html',{'abstract_request':abstract_request},context_instance=RequestContext(request))

    if abstract_request.get_status() == 'pending':
        return render_to_response('public/abstracts/content-pending.html',{'abstract_request':abstract_request},context_instance=RequestContext(request))
    elif abstract_request.get_status() == 'complete':
        return render_to_response('public/abstracts/content-finished.html',{'abstract_request':abstract_request},context_instance=RequestContext(request))

    if member:
        content_submission_form_details = AbstractSubmissionFormDetails(initial={'title':member.title,'given_name':member.given_name,'surname':member.surname,'email':member.user.email,'telephone':member.telephone})
    else:
        content_submission_form_details = AbstractSubmissionFormDetails()

    if request.POST:
        content_submission_form_details = AbstractSubmissionFormDetails(request.POST)

        if content_submission_form_details.is_valid():

            #try:
            content_submission = content_submission_form_details.save(commit=False)
            content_submission.abstract_request = abstract_request
            if member:
                content_submission.member = member
            else:
                try:
                    abstract_member = Member.objects.get(user__email=content_submission.email)
                    content_submission.member = abstract_member
                except Member.DoesNotExist:
                    try:
                        user = User.objects.get(email=content_submission.email)
                    except User.DoesNotExist:
                        user = User(email=content_submission.email,first_name=content_submission.given_name,last_name=content_submission.surname)
                        user.username = random_string_unique(20,User,'username')
                        password = generate_random_password(10)
                        user.set_password(password)
                        user.save()
                        content_submission.member_registered = True

                    non_member = Member(user=user,user_type='non-member',given_name = content_submission.given_name,surname=content_submission.surname,title=content_submission.title)
                    if content_submission.member_registered:
                        non_member.raw_password = password
                    non_member.membership_number = get_next_membership_number()
                    non_member.save()

                    content_submission.member = non_member

            content_submission.unique_key = random_string_unique(20,AbstractSubmission,'unique_key')
            content_submission.save()
            content_submission.unique_code = content_submission.get_unique_code()
            content_submission.save()

            request.session['content_submission_key'] = content_submission.unique_key

            return HttpResponseRedirect(reverse('abstract_submission_content',args=[abstract_request.slug]))

            #except:
            #    messages.error(request,'Could not save your submission, please try again.')
            #    if content_submission.id:
            #        content_submission.delete()

    return render_to_response('public/abstracts/submit-abstract.html',{'abstract_request':abstract_request,'content_submission_form_details':content_submission_form_details},context_instance=RequestContext(request))


def submission_content(request,abstract_request_slug,content_submission_key=False):

    abstract_request = get_object_or_404(AbstractRequest,slug=abstract_request_slug)

    try:
        member = Member.objects.get(user=request.user)
    except:
        member = False

    if content_submission_key:
        content_submission = get_object_or_404(AbstractSubmission,unique_key=content_submission_key)
    elif request.session.get('content_submission_key', False):
        content_submission = get_object_or_404(AbstractSubmission,unique_key=request.session['content_submission_key'])
    else:
        raise Http404

    if content_submission.complete:
        return HttpResponseRedirect(reverse('abstract_submission_complete',args=[abstract_request.slug]))

    content_submission_title_form = AbstractSubmissionTitleForm(instance=content_submission,fields_required=True)
    content_submission_data_form = AbstractSubmissionDataForm(instance=content_submission,fields_required=True)
    confirmation_form = ConfirmationForm(instance=content_submission)
    authors = AbstractSubmissionAuthor.objects.filter(content_submission=content_submission).order_by('order')

    choices = ()
    author_forms = []
    if authors:
        for author in authors:
            author_form = AbstractSubmissionAuthorForm(instance=author,prefix='author_%s' % (author.order))
            author_forms.append(author_form)

            if author.order == 1:
                choices = choices + ((u'First Author and Primary Contact',u'First Author and Primary Contact'),)
            else:
                choices = choices + ((u'Author %s' % (author.order), u'Author %s' % (author.order)),)

    else:
        submission_name = "%s %s" % (content_submission.given_name,content_submission.surname)
        author_form = AbstractSubmissionAuthorForm(prefix='author_1',initial={'name':submission_name,'email':content_submission.email,'telephone':content_submission.telephone})
        author_forms.append(author_form)
        choices = choices + ((u'First Author and Primary Contact',u'First Author and Primary Contact'),)

    content_submission_data_form.fields['presenter'].widget.choices = choices

    files = AbstractSubmissionFile.objects.filter(content_submission=content_submission).order_by('order')
    file_forms = []
    if files:
        for file in files:
            file_form = AbstractSubmissionFileForm(instance=file,prefix='file_%s' % (file.order))
            file_form.fields['file'].label = 'Image'
            file_forms.append(file_form)
    else:
        file_form = AbstractSubmissionFileForm(prefix='file_1')
        file_forms.append(file_form)

    if request.POST:

        content_submission_title_form = AbstractSubmissionTitleForm(request.POST,instance=content_submission,fields_required=True)
        content_submission_data_form = AbstractSubmissionDataForm(request.POST,instance=content_submission,fields_required=True)
        confirmation_form = ConfirmationForm(request.POST, instance=content_submission)

        for author in authors:
            author.delete()

        posted_authors = request.POST.getlist('authors')
        author_forms = []
        author_order = 1
        author_errors = False

        choices = ()

        for posted_author in posted_authors:
            author_form = AbstractSubmissionAuthorForm(request.POST,prefix='author_%s' % (posted_author))
            author_forms.append(author_form)

            if posted_author == '1':
                choices = choices + ((u'First Author and Primary Contact',u'First Author and Primary Contact'),)
            else:
                choices = choices + ((u'Author %s' % (posted_author), u'Author %s' % (posted_author)),)

            if not author_form.is_valid():
                author_errors = True
            else:
                submitted_author = author_form.save(commit=False)
                submitted_author.content_submission = content_submission
                submitted_author.order = author_order
                submitted_author.save()
                author_order = author_order + 1

        content_submission_data_form.fields['presenter'].widget.choices = choices

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

        for posted_file in posted_files:

            try:
                #existing_file
                existing_file = AbstractSubmissionFile.objects.get(content_submission=content_submission,order=posted_file)
                file_form = AbstractSubmissionFileForm(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()

                existing_file_form = AbstractSubmissionFileForm(instance=existing_file,prefix='file_%s' % (posted_file))
                file_forms.append(existing_file_form)
                current_files.append(existing_file)

            except AbstractSubmissionFile.DoesNotExist:

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

                    new_file_form = AbstractSubmissionFileForm(instance=submitted_file,prefix='file_%s' % (posted_file))
                    file_forms.append(new_file_form)

                else:
                    file_errors = True
                    file_form = AbstractSubmissionFileForm(request.POST,request.FILES,prefix='file_%s' % (posted_file))
                    file_forms.append(file_form)

            file_order = file_order + 1


        for file in files:
            if file not in current_files:
                file.delete()

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

            if content_submission_title_form.is_valid() and content_submission_data_form.is_valid() and confirmation_form.is_valid() and not author_errors:

                content_submission_title_form.save()
                content_submission_data_form.save()
                confirmation_form.save()

                content_submission.complete = True
                content_submission.save()

                #do final checks that all is okay and proceed as final submission
                emails.abstract_content_submitted(request=request,content_submission=content_submission)

                if content_submission.member_registered:
                    non_member_registered.send(sender=None,request=request,member=content_submission.member,title=abstract_request.name)

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

                return HttpResponseRedirect(reverse('abstract_submission_complete',args=[abstract_request.slug]))

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

            content_submission_title_form_temp = AbstractSubmissionTitleForm(request.POST,instance=content_submission,fields_required=False)
            if content_submission_title_form_temp.is_valid():
                content_submission_title_form_temp.save()
            content_submission_data_form_temp = AbstractSubmissionDataForm(request.POST,instance=content_submission,fields_required=False)
            if content_submission_data_form_temp.is_valid():
                content_submission_data_form_temp.save()

            if content_submission.first_save:
                #send email to confirm
                emails.abstract_content_saved(request=request,content_submission=content_submission)

                content_submission.first_save = False
                content_submission.save()

                messages.success(request,'Your data has been saved. You should receive an email detailing how to resume this submission at a later date.')
            else:
                messages.success(request,'Your data has been saved.')
    return render_to_response('public/abstracts/submit-content.html',{'abstract_request':abstract_request,'content_submission':content_submission,'content_submission_title_form':content_submission_title_form,'authors':authors,'author_forms':author_forms,'content_submission_data_form':content_submission_data_form,'confirmation_form':confirmation_form,'file_forms':file_forms},context_instance=RequestContext(request))


def submission_complete(request,abstract_request_slug):

    abstract_request = get_object_or_404(AbstractRequest,slug=abstract_request_slug,enabled=True)

    return render_to_response('public/abstracts/submit-content-complete.html',{'abstract_request':abstract_request},context_instance=RequestContext(request))
