from crispy_forms.helper import FormHelper
from django import forms
from django.contrib.auth.models import User
from django.contrib.postgres.forms import HStoreField
from django.urls import resolve
from django.utils.translation import ugettext_lazy as _

from .models import (Alert, AppSettings, DataFile, DataSet, Institution, Lab,
                     Profile)


class BaseNestedFormSet(forms.BaseFormSet):
    def is_valid(self):
        result = super().is_valid()

        if self.is_bound:
            for form in self.forms:
                if hasattr(form, 'nested'):
                    result = result and form.nested.is_valid()

        return result


class BaseInlineNestedFormSet(forms.BaseInlineFormSet):
    def is_valid(self):
        result = super().is_valid()

        if self.is_bound:
            for form in self.forms:
                if hasattr(form, 'nested'):
                    result = result and form.nested.is_valid()

        return result

    def save(self, commit=True):
        result = super().save(commit=commit)

        for form in self.forms:
            if hasattr(form, 'nested'):
                if not self._should_delete_form(form):
                    form.nested.save(commit=commit)

        return result


class AlertForm(forms.ModelForm):
    class Meta:
        model = Alert
        fields = ['id', 'message_en', 'message_fr', 'start', 'end']
        labels = {
            'message_en': _('Message (English)'),
            'message_fr': _('Message (French)'),
            'start': _('Start'),
            'end': _('End')
        }
        widgets = {
            'message_en': forms.Textarea(attrs={'rows': 3}),
            'message_fr': forms.Textarea(attrs={'rows': 3}),
        }


class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')

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

        if self.instance.pk and self.instance.profile.accountname:
                self.fields['first_name'].disabled = True
                self.fields['last_name'].disabled = True
                self.fields['email'].disabled = True

        else:
            self.fields['first_name'].required = True
            self.fields['last_name'].required = True


class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        exclude = ('user', 'accountname')
        widgets = {'labs': forms.CheckboxSelectMultiple()}


class InstitutionForm(forms.ModelForm):
    class Meta:
        model = Institution
        fields = ('__all__')


class BasicDataFileForm(forms.ModelForm):
    class Meta:
        model = DataFile
        fields = ('file',)


class DataFileAnnotationForm(forms.Form):
    dropzone_files = forms.CharField(required=False, widget=forms.HiddenInput)
    annotations = HStoreField(required=False)


class DataSetForm(forms.ModelForm):
    class Meta:
        model = DataSet
        fields = ('__all__')


class LabForm(forms.ModelForm):
    class Meta:
        model = Lab
        fields = ('__all__')


class LabSelectionForm(forms.Form):
    lab = forms.ChoiceField(required=True)
    redirect_to = forms.CharField(max_length=256, required=True, widget=forms.HiddenInput)

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if request.user.is_authenticated:
            self.fields['lab'].choices = [(lab.id, lab.name) for lab in request.user.profile.labs.all()]
            self.fields['lab'].initial = request.session.get('active_lab_id')

        self.fields['redirect_to'].initial = resolve(request.path_info).url_name

        self.helper = FormHelper()
        self.helper.form_show_labels = False


class AppSettingsForm(forms.ModelForm):
    class Meta:
        model = AppSettings
        fields = ('__all__')