"""File containing member forms."""

from django import forms
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from members.models import Member, Payment, Request

import csv
import logging
from dal import autocomplete


class CSVValidationError(Exception):
    def __init__(self, form_errors):
        self.form_errors = form_errors


class MemberForm(forms.ModelForm):
    """Member model form."""

    class Meta:
        """Meta for Member model form."""

        model = Member
        fields = ["first_name", "last_name", "email", "POR", "AYY", "jas"]

    class ImportResult:
        def __init__(self, members, payments):
            self.members = members
            self.payments = payments

    def _clean_boolean_field(self, key):
        value = self.data.get(key, None)
        if value in ["1", "0"]:
            return bool(int(value))
        else:
            return value == "on"

    def clean_jas(self):
        return self._clean_boolean_field("jas")

    def clean_AYY(self):
        return self._clean_boolean_field("AYY")

    @staticmethod
    def csv_to_models(data, payment_source="AYY", delimiter=","):
        clean_data = data.strip().split("\n")
        clean_data = [row.rstrip(",").rstrip("\r").strip() for row in clean_data]
        csv_reader = csv.DictReader(
            clean_data,
            fieldnames=MemberForm.Meta.fields,
            delimiter=delimiter,
            quoting=csv.QUOTE_NONE,
        )

        members = []
        payments = []
        for line in csv_reader:
            try:
                for key, value in line.items():
                    line[key] = value.strip()
            except AttributeError as ex:
                logging.error('Invalid line in CSV: "{}"'.format(line))
                logging.error("Delimiter: {}".format(delimiter))
                raise

            email = line["email"]
            member_exists = False
            if Member.objects.filter(email=email).exists():
                member_exists = True

            if not member_exists:
                form = MemberForm(line)
                if not form.is_valid():
                    raise CSVValidationError(form.errors)

                model = form.save(commit=False)
                members.append(model)

            else:
                member = Member.objects.get(email=email)
                payment_data = {
                    "source": payment_source,
                    "member": member.id,
                    "date": timezone.now(),
                }
                form = PaymentForm(payment_data)
                if not form.is_valid():
                    raise CSVValidationError(form.errors)

                model = form.save(commit=False)
                payments.append(model)

        return MemberForm.ImportResult(members, payments)


class PaymentForm(forms.ModelForm):
    """Payment model form."""

    member = forms.ModelChoiceField(
        queryset=Member.objects.all(),
        widget=autocomplete.ModelSelect2(url="member-autocomplete"),
    )

    class Meta:
        """Meta for Payment model form."""

        model = Payment
        fields = ["date", "source", "member"]
        labels = {"member": _("Member")}


class ApplicationForm(forms.ModelForm):
    """Member application model form."""

    class Meta:
        """Meta for application model form."""

        model = Request
        fields = ["first_name", "last_name", "email", "AYY", "jas", "POR"]

    def __init__(self, *args, **kwargs):
        super(ApplicationForm, self).__init__(*args, **kwargs)

        self.fields["AYY"].label = _("I'm a member of AYY")
        self.fields["jas"].label = _("I want to receive a weekly newsletter")


class UploadFileForm(forms.Form):
    file = forms.FileField()
