#Django core bits
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib import messages
from django.contrib.auth.models import User, Group
from django.core.mail import EmailMessage
from django.http import HttpResponse

import random,string,csv

from datetime import datetime, date, time
from models import *
from forms import *

from signals import *

from modules.core.functions import random_string_unique


def register_member(request,approval_required=False):

    errors = False

    registration_form_user = RegistrationFormUser(request.POST)
    registration_form_password = RegistrationFormPassword(request.POST)
    registration_form_personal = RegistrationFormPersonal(request.POST)
    registration_form_member_type = RegistrationFormMemberType(request.POST)
    registration_form_hospital = RegistrationFormHospital(request.POST)
    registration_form_personal_address = RegistrationFormPersonalAddress(request.POST)
    registration_form_are_trainee = RegistrationFormAreTrainee(request.POST)
    registration_form_training = RegistrationFormTraining(request.POST)
    registration_form_professional = RegistrationFormProfessional(request.POST)
    registration_form_support = RegistrationFormSupport(request.POST, request.FILES)
    registration_form_terms = RegistrationFormTerms(request.POST)

    if registration_form_user.is_valid() and registration_form_password.is_valid() and registration_form_personal.is_valid() and registration_form_member_type.is_valid() and registration_form_hospital.is_valid() and registration_form_personal_address.is_valid() and registration_form_training.is_valid() and registration_form_professional.is_valid() and registration_form_support.is_valid() and registration_form_terms.is_valid():

        if not errors:
            #create user
            user = registration_form_user.save(commit=False)
            user.username = random_string_unique(20,User,'username')
            user.set_password(registration_form_password.cleaned_data['password1'])
            user.save()

            #try:
            member = registration_form_personal.save(commit=False)
            member.user = user
            member.user_type = 'member'
            member.save()

            user.first_name = member.given_name
            user.last_name = member.surname
            user.save()

            registration_form_member_type = RegistrationFormMemberType(request.POST,instance=member)
            registration_form_member_type.save()

            registration_form_hospital = RegistrationFormHospital(request.POST,instance=member)
            registration_form_hospital.save()

            registration_form_personal_address = RegistrationFormPersonalAddress(request.POST,instance=member)
            registration_form_personal_address.save()

            registration_form_are_trainee = RegistrationFormAreTrainee(request.POST,instance=member)
            registration_form_are_trainee.save()

            registration_form_training = RegistrationFormTraining(request.POST,instance=member)
            registration_form_training.save()

            registration_form_professional = RegistrationFormProfessional(request.POST,instance=member)
            registration_form_professional.save()

            registration_form_know_existing = RegistrationFormKnowExisting(request.POST,instance=member)
            registration_form_know_existing.save()

            registration_form_support = RegistrationFormSupport(request.POST, request.FILES, instance=member)
            registration_form_support.save()

            registration_form_terms = RegistrationFormTerms(request.POST, instance=member)
            registration_form_terms.save()

            if member.referrer_email:
                unique_key = random_string_unique_referrer()
                member.referrer_key = unique_key

            return member

    messages.error(request,'Please ensure you complete all the fields to continue')

    return False

def get_next_membership_number():

    members = Member.objects.filter(membership_number__isnull=False).order_by('-membership_number')
    if members:
        last_member = members[0]
        return last_member.membership_number + 1
    else:
        return 1

def random_string_unique_referrer():

    while True:
        random_str = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(50))

        if (not Member.objects.filter(**{'referrer_key':random_str}).count()) and (not Member.objects.filter(**{'referrer2_key':random_str}).count()):
            return random_str

def find_updated_fields(request,member,user_form,forms=[]):

    updated_fields = []

    for field in user_form:
        original_val = getattr(member.user,field.name)
        if original_val != request.POST[field.name]:
            updated_fields.append({'field':field.label,'old':original_val,'new':request.POST[field.name]})

    for form in forms:
        for field in form:
            original_val = getattr(member,field.name)
            new_val  = ''
            if request.POST.get(field.name):
                new_val = request.POST[field.name]
                if new_val == 'on':
                    new_val = 'True'
                elif new_val == 'off':
                    new_val = 'False'

            if field.name == 'country' or field.name == 'hospital_country':
                if original_val:
                    original_val_id = str(original_val.id)
                    original_val_name = original_val.name
                    if original_val_id != request.POST[field.name]:
                        if field.name == 'country' or field.name == 'hospital_country':
                            country = Country.objects.get(id=request.POST[field.name])
                            updated_fields.append({'field':field.label,'old':original_val_name,'new':country.name})
            elif field.name == 'training_commencement':
                if original_val:
                    original_val = original_val.strftime('%d/%m/%Y')
                else:
                    original_val = ''

                if original_val != new_val:
                    updated_fields.append({'field':field.label,'old':original_val,'new':new_val})

            elif field.name == 'professional_certification' or field.name == 'other_qualifications':
                original_values = original_val.all()
                new_values = request.POST.getlist(field.name)
                different = False
                if len(original_values) != len(new_values):
                    different = True
                else:
                    for original_value in original_values:
                        if str(original_value.id) not in new_values:
                            different = True
                if different:
                    old_string = ''
                    new_string = ''
                    for original_value in original_values:
                        old_string = "%s%s," % (old_string,original_value.name)
                    for new_value in new_values:
                        if field.name == 'professional_certification':
                            try:
                                certification = ProfessionalChoice.objects.get(id=new_value)
                                new_string = "%s%s," % (new_string,certification.name)
                            except:
                                pass
                        elif field.name == 'other_qualifications':
                            try:
                                qualification = QualificationChoice.objects.get(id=new_value)
                                new_string = "%s%s," % (new_string,qualification.name)
                            except:
                                pass
                    updated_fields.append({'field':field.label,'old':old_string,'new':new_string})
            else:
                try:
                    original_val = str(original_val)
                    if original_val != new_val:
                        updated_fields.append({'field':field.label,'old':original_val,'new':new_val})
                except:
                    pass

    return updated_fields

def export_members(request,members,referrers=False):

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

    writer = csv.writer(response)

    if referrers:
        writer.writerow(['Membership Number','Title','First Name','Last Name','Email Address','Type','Registered','Expiry Date','Date of Birth','Address 1','Address 2','Address 3','Town','County','Country','Postcode','Telephone','Job Title','Institution / Company','Hospital / Affiliation','Hospital Postcode','Department Manager\'s Email','Trainee','Type of Training','Other Training','Training Commencement','Professional Certification','Other Professional Certification','Other Qualifications','Ref 1 Email','Ref 2 Email','Ref 1 Name (Offline)','Ref 1 Contact','Ref 2 Name (Offline)','Ref 2 Contact'])
    else:
        writer.writerow(['Membership Number','Title','First Name','Last Name','Email Address','Type','Registered','Expiry Date','Date of Birth','Address 1','Address 2','Address 3','Town','County','Country','Postcode','Telephone','Job Title','Institution / Company','Hospital / Affiliation','Hospital Postcode','Department Manager\'s Email','Trainee','Type of Training','Other Training','Training Commencement','Professional Certification','Other Professional Certification', 'AVS Search', 'AVS Date', 'Other Qualifications'])

    for member in members:

        professional_certification = ""
        for certification in member.professional_certification.all():
            professional_certification = "%s%s " % (professional_certification,certification)

        qualifications = ""
        for qualification in member.other_qualifications.all():
            qualifications = "%s%s " % (qualifications,qualification)

        if referrers:
            writer.writerow([unicode(s).encode("utf-8") for s in (member.membership_number,member.title,member.given_name,member.surname,member.user.email,member.member_type,member.user.date_joined,member.expiry_date,member.date_of_birth,member.address_1,member.address_2,member.address_3,member.town,member.county,member.country,member.postcode,member.telephone,member.job_title,member.institution_company,member.hospital,member.hospital_postcode,member.department_manager_email,member.trainee,member.type_of_training,member.other_training,member.training_commencement,professional_certification,member.other_professional_certification,member.avs_date,qualifications,member.referrer_email,member.referrer2_email,member.referee_new_1_name,member.referee_new_1_details,member.referee_new_2_name,member.referee_new_2_details)])
        else:
            writer.writerow([unicode(s).encode("utf-8") for s in (member.membership_number,member.title,member.given_name,member.surname,member.user.email,member.member_type,member.user.date_joined,member.expiry_date,member.date_of_birth,member.address_1,member.address_2,member.address_3,member.town,member.county,member.country,member.postcode,member.telephone,member.job_title,member.institution_company,member.hospital,member.hospital_postcode,member.department_manager_email,member.trainee,member.type_of_training,member.other_training,member.training_commencement,professional_certification,member.other_professional_certification,member.avs_opt_in, member.avs_date,qualifications)])

    return response
