"""
This module contains the form class for the contact_form app.

"""
from __future__ import absolute_import, unicode_literals

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from django import forms
from django.conf import settings
from django.contrib.sites.models import Site
from django.contrib.sites.requests import RequestSite
from django.core.mail import send_mail
from django.template import RequestContext, loader
from django.urls import reverse
from django.utils.translation import gettext_lazy as _


class ContactForm(forms.Form):
    """
    This is the contact form class.

    """

    name = forms.CharField(max_length=100, label=_("Your name"))
    email = forms.EmailField(max_length=200, label=_("Your email address"))
    body = forms.CharField(widget=forms.Textarea, label=_("Your message"))

    subject_template_name = "contact_form/contact_form_subject.txt"
    template_name = "contact_form/contact_form.txt"
    from_email = settings.DEFAULT_FROM_EMAIL
    recipient_list = [mail_tuple[1] for mail_tuple in settings.MANAGERS]

    def __init__(self, **kwargs):
        self.request = kwargs.pop("request")
        super(ContactForm, self).__init__(**kwargs)
        self.helper = FormHelper()
        self.helper.form_action = reverse("contact_form")
        self.helper.add_input(Submit("submit", _("Send message")))

    def get_context(self):
        if not self.is_valid():
            raise ValueError("Cannot generate context from invalid contact form")
        if Site._meta.installed:
            site = Site.objects.get_current()
        else:
            site = RequestSite(self.request)
        return RequestContext(self.request, dict(self.cleaned_data, site=site))

    def message(self):
        context = self.get_context()
        template_context = context.flatten()
        template_context.update({"remote_ip": context.request.META["REMOTE_ADDR"]})
        return loader.render_to_string(self.template_name, template_context)

    def subject(self):
        context = self.get_context().flatten()
        subject = loader.render_to_string(self.subject_template_name, context)
        return "".join(subject.splitlines())

    def save(self, fail_silently=False):
        """
        Build and send the email.

        """
        send_mail(
            fail_silently=fail_silently,
            from_email=self.from_email,
            recipient_list=self.recipient_list,
            subject=self.subject(),
            message=self.message(),
        )
