"""
Created on 03.10.2011

@author: Christian
"""
from django.conf import settings
from django.contrib import auth
from django.contrib.sites.models import Site
from django.utils.translation import ugettext_lazy as _

from . import models
from utils.html5 import forms
from utils.massmailer import MassMailer


class MembershipForm(forms.ModelForm):
    error_css_class = 'error'
    required_css_class = 'required'
    birthday = forms.DateField(label=_('birthday'), required=False)

    class Meta:
        model = models.Membership
        fields = (
            'username', 'gender', 'first_name', 'last_name', 'email', 'avatar',
            'website', 'membership', 'birthday', 'telephone', 'street_name',
            'post_code', 'city', 'comment'
        )

    def clean_birthday(self):
        if self.cleaned_data['membership'] and not self.cleaned_data[
            'birthday']:
            raise forms.ValidationError(_('For your membership, we need this. \
            Please fill out this field yet.'))
        return self.cleaned_data['birthday']

    def clean_telephone(self):
        if self.cleaned_data['membership'] and not self.cleaned_data[
            'telephone']:
            raise forms.ValidationError(_('For your membership, we need this. \
            Please fill out this field yet.'))
        return self.cleaned_data['telephone']

    def clean_street_name(self):
        if self.cleaned_data['membership'] and not self.cleaned_data[
            'street_name']:
            raise forms.ValidationError(_('For your membership, we need this. \
            Please fill out this field yet.'))
        return self.cleaned_data['street_name']

    def clean_post_code(self):
        if self.cleaned_data['membership'] and not self.cleaned_data[
            'post_code']:
            raise forms.ValidationError(_('For your membership, we need this. \
            Please fill out this field yet.'))
        return self.cleaned_data['post_code']

    def clean_city(self):
        if self.cleaned_data['membership'] and not self.cleaned_data['city']:
            raise forms.ValidationError(_('For your membership, we need this. \
             Please fill out this field yet.'))
        return self.cleaned_data['city']


class RegistrationForm(forms.ModelForm):
    """
    Form to register a new user account.
    Validates that the requested username and email is not already in use,
    requires the password to be entered twice to catch typos.
    sends an activation request per mail, to validate the eMail.
    """
    error_css_class = 'error'
    required_css_class = 'required'

    first_name = forms.CharField(max_length=30, required=True,
                                 label=_('Given Name'))
    last_name = forms.CharField(max_length=30, required=True,
                                label=_('Last Name'))
    username = forms.SlugField(required=True, max_length=30,
                               label=_('Username'),
                               help_text=_("The Username can only contain the letters from A to Z, \
        Numbers, and the underscore. It must be at least 2 characters long, \
        and cannot be longer the 30. The first character must be a letter."))
    email = forms.EmailField(required=True)
    password1 = forms.CharField(widget=forms.PasswordInput(),
                                label=_('password'))
    password2 = forms.CharField(widget=forms.PasswordInput(),
                                label=_('password (again)'))
    recaptcha = forms.ReCaptchaField()

    class Meta:
        model = auth.get_user_model()
        fields = ('first_name', 'last_name', 'username', 'email',)

    def clean_username(self):
        """
        Validate that the username is not already in use.
        """
        try:
            auth.get_user_model().objects.get(
                username__iexact=self.cleaned_data['username']
            )
        except auth.get_user_model().DoesNotExist:
            return self.cleaned_data['username']
        raise forms.ValidationError(_(u'This username is already taken. \
        Please choose another.'))

    def clean_email(self):
        """
        Validate that the supplied email address is unique for the site.
        """
        if auth.get_user_model().objects.filter(
                email__iexact=self.cleaned_data['email']):
            raise forms.ValidationError(_(u'This email address is already in \
            use. Please supply a different email address.'))
        return self.cleaned_data['email']

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1", "")
        password2 = self.cleaned_data["password2"]
        if password1 != password2:
            raise forms.ValidationError(
                _("The two password fields didn't match."))
        return password2

    def send_email(self, activation):
        mailer = MassMailer()
        mailer.subject = 'Deine Anmeldung auf %s' % Site.objects.get_current()
        mailer.txt_template = 'membership/email/activation_email.txt'
        mailer.context = {
            'user': activation.user,
            'site': Site.objects.get_current(),
            'activation_key': activation.activation_key,
            'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
        }
        mailer.add_recipient(activation.user)
        mailer.send()

    def save(self, commit=True):
        """
        Creates the new ``User`` and ``RegistrationProfile`` and
        returns the ``User``.
        """
        user = super(RegistrationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        user.is_active = False
        if commit:
            user.save()
            activation = models.ActivationRequest.objects.create_pending_registration(user)  # @IgnorePep8
            self.send_email(activation)
        return user
