from django.forms import ModelForm, ValidationError
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.forms import UserCreationForm, UsernameField
from django.contrib.auth import get_user_model

from .models import Signature, PetitionTemplate, Petition
from .widgets import SwitchField

import uuid
from tinymce.widgets import TinyMCE


class SignatureForm(ModelForm):
    class Meta:
        model = Signature
        fields = ['first_name', 'last_name', 'phone', 'email', 'subscribed_to_mailinglist']
        widgets = {
            'first_name': forms.TextInput(attrs={'placeholder': _('First name *'), 'class': 'form-control has-feedback eaFullWidthContent'}),
            'last_name': forms.TextInput(attrs={'placeholder': _('Last name *'), 'class': 'form-control has-feedback eaFullWidthContent'}),
            'phone': forms.TextInput(attrs={'placeholder': _('Phone number'), 'class': 'form-control has-feedback eaFullWidthContent'}),
            'email': forms.EmailInput(attrs={'placeholder': _('Email address *'), 'class': 'form-control has-feedback eaFullWidthContent'})
        }

        labels = { f : '' for f in  ['first_name', 'last_name', 'phone', 'email'] }

    def __init__(self, petition=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.instance.petition = petition
        if not petition.has_newsletter:
            del self.fields['subscribed_to_mailinglist']
        else:
            self.fields['subscribed_to_mailinglist'].label = self.instance.petition.newsletter_text

    def save(self, commit=True):
        object = super().save(commit=False)
        hashstring = str(uuid.uuid4())
        object.confirmation_hash = hashstring
        object.confirmed = False
        if commit:
            object.save()
        return object


class PetitionCreationStep1(forms.Form):
    ### Ask for title ###
    title = forms.CharField(max_length=200)


class PetitionCreationStep2(forms.Form):
    ### Ask for content ###
    message = forms.CharField(widget=TinyMCE)


class PetitionCreationStep3(forms.Form):
    ### Ask for publication ###
    publish = forms.BooleanField(required=False, label=_("Publish the petition now?"))
    configure = forms.BooleanField(required=False, label=_("Save & Configure"))


class ContentFormGeneric(forms.Form):
    ### Content of a Petition ###
    text = forms.CharField(widget=TinyMCE)
    side_text = forms.CharField(widget=TinyMCE, required=False)
    footer_text = forms.CharField(widget=TinyMCE, required=False)
    footer_links = forms.CharField(widget=TinyMCE, required=False)
    sign_form_footer = forms.CharField(required=False)


class ContentFormPetition(ContentFormGeneric):
    title = forms.CharField(max_length=200)
    field_order = ('title', )


class ContentFormTemplate(ContentFormGeneric):
    name = forms.CharField(max_length=50)
    field_order = ('name', )


class EmailForm(forms.Form):
    ### E-mail settings of Petition ###
    use_custom_email_settings = SwitchField(required=False, label=_("Use custom e-mail settings?"))
    confirmation_email_sender = forms.EmailField(max_length=100, required=False)
    confirmation_email_smtp_host = forms.CharField(max_length=100, required=False)
    confirmation_email_smtp_port = forms.IntegerField(required=False)
    confirmation_email_smtp_user = forms.CharField(max_length=200, required=False)
    confirmation_email_smtp_password = forms.CharField(max_length=200, required=False, widget=forms.PasswordInput())
    confirmation_email_smtp_tls = SwitchField(required=False, label=_("Use TLS?"))
    confirmation_email_smtp_starttls = SwitchField(required=False, label=_("Use STARTTLS?"))

    confirmation_email_smtp_port.widget.attrs.update({'min': 1, 'max': 65535})

    def clean(self):
        # FIXME: WIP
        cleaned_data = super(EmailForm, self).clean()
        data = {}
        for field in self.base_fields:
            data[field] = cleaned_data.get(field)

        if data['confirmation_email_smtp_tls'] and data['confirmation_email_smtp_starttls']:
            self.add_error('confirmation_email_smtp_tls', ValidationError(_("You cannot select both TLS and STARTTLS."), code="invalid"))

        if data['confirmation_email_smtp_port'] < 1 or data['confirmation_email_smtp_port'] > 65535:
            self.add_error('confirmation_email_smtp_port', ValidationError(_("SMTP port must be >= 1 and <= 65535"),
                                                                           code="invalid"))
        return self.cleaned_data


class SocialNetworkForm(forms.Form):
    ### Social Network settings of Petition ###
    twitter_description = forms.CharField(max_length=200, required=False)
    twitter_image = forms.CharField(max_length=500, required=False)
    org_twitter_handle = forms.CharField(max_length=20, required=False)


class NewsletterForm(forms.Form):
    ### Newsletter settings of Petition ###
    has_newsletter = SwitchField(required=False, label=_("Does this petition have a newsletter?"))
    newsletter_subscribe_http_data = forms.CharField(required=False)
    newsletter_subscribe_http_mailfield = forms.CharField(max_length=100,required=False)
    newsletter_subscribe_http_url = forms.CharField(max_length=1000, required=False)
    newsletter_subscribe_mail_subject = forms.CharField(max_length=1000, required=False)
    newsletter_subscribe_mail_from = forms.EmailField(required=False)
    newsletter_subscribe_mail_to = forms.EmailField(required=False)
    newsletter_subscribe_method = forms.ChoiceField(choices=Petition.NEWSLETTER_SUBSCRIBE_METHOD_CHOICES, required=False)
    newsletter_subscribe_mail_smtp_host = forms.CharField(max_length=100, required=False)
    newsletter_subscribe_mail_smtp_port = forms.IntegerField(required=False)
    newsletter_subscribe_mail_smtp_user = forms.CharField(max_length=200, required=False)
    newsletter_subscribe_mail_smtp_password = forms.CharField(max_length=200, required=False,
                                                              widget=forms.PasswordInput())
    newsletter_subscribe_mail_smtp_tls = SwitchField(required=False, label=_("Use TLS?"))
    newsletter_subscribe_mail_smtp_starttls = SwitchField(required=False, label=_("Use STARTTLS?"))

    newsletter_subscribe_mail_smtp_port.widget.attrs.update({'min': 1, 'max': 65535})

    def clean(self):
        # FIXME: WIP
        cleaned_data = super(NewsletterForm, self).clean()
        data = {}
        for field in self.base_fields:
            data[field] = cleaned_data.get(field)

        if data['newsletter_subscribe_mail_smtp_tls'] and data['newsletter_subscribe_mail_smtp_starttls']:
            self.add_error('newsletter_subscribe_mail_smtp_tls', ValidationError(_("You cannot select both TLS and STARTTLS."), code="invalid"))

        if data['newsletter_subscribe_mail_smtp_port'] < 1 or data['newsletter_subscribe_mail_smtp_port'] > 65535:
            self.add_error('newsletter_subscribe_mail_smtp_port', ValidationError(_("SMTP port must be >= 1 and <= 65535"),
                                                                                  code="invalid"))

        return self.cleaned_data


class PytitionUserCreationForm(UserCreationForm):
    class Meta:
        model = get_user_model()
        fields = ("username", "first_name", "last_name", "email")
        field_classes = {'username': UsernameField}

    def __init__(self, *args, **kwargs):
        super(PytitionUserCreationForm, self).__init__(*args, **kwargs)
        self.fields['first_name'].required = True
        self.fields['email'].required = True
