from datetime import datetime

from django import forms
from django.forms import ModelForm, Form

from models import Subject, Worker, Appointment, Visit

"""
Possible redundancy, but if need arises, contents of forms can be easily customized
"""

CURRENT_YEAR = datetime.now().year
YEAR_CHOICES = tuple(range(CURRENT_YEAR, CURRENT_YEAR - 120, -1))
FUTURE_YEAR_CHOICES = tuple(range(CURRENT_YEAR, CURRENT_YEAR + 5, 1))
DATEPICKER_DATE_ATTRS = {
    'class': 'datepicker',
    'data-date-format': 'yyyy-mm-dd',
    'data-date-orientation': 'bottom'
}
DATETIMEPICKER_DATE_ATTRS = {
    'class': 'datetimepicker',
    'data-date-format': 'Y-MM-DD HH:mm',
}


def validate_subject_nd_number(self):
    subject = self.cleaned_data
    if subject['nd_number'] != "":
        subjects_from_db = Subject.objects.filter(nd_number=subject['nd_number'])
        if subjects_from_db:
            if subjects_from_db[0].screening_number != subject.get('screening_number', ''):
                self.add_error('nd_number', "ND number already in use")


class SubjectAddForm(ModelForm):
    date_born = forms.DateField(label="Date of birth",
                                widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
                                required=False
                                )

    datetime_contact_reminder = forms.DateField(label="Contact on",
                                                widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
                                                required=False
                                                )

    class Meta:
        model = Subject
        fields = '__all__'

    def clean(self):
        subject = self.cleaned_data

        subjects_from_db = Subject.objects.filter(screening_number=subject.get('screening_number', ''))

        if len(subjects_from_db) > 0:
            self.add_error('screening_number', "Screening number already in use")

        validate_subject_nd_number(self)


class SubjectDetailForm(ModelForm):
    class Meta:
        model = Subject
        fields = '__all__'


class SubjectEditForm(ModelForm):
    datetime_contact_reminder = forms.DateField(label="Contact on",
                                                widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
                                                required=False
                                                )
    date_born = forms.DateField(label="Date of birth",
                                widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
                                required=False
                                )

    def __init__(self, *args, **kwargs):
        super(SubjectEditForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.id:
            self.fields['screening_number'].widget.attrs['readonly'] = True

    def clean_screening_number(self):
        instance = getattr(self, 'instance', None)
        if instance and instance.id:
            return instance.screening_number
        else:
            return self.cleaned_data['screening_number']

    def clean(self):
        validate_subject_nd_number(self)

    class Meta:
        model = Subject
        fields = '__all__'


class WorkerAddForm(ModelForm):
    class Meta:
        model = Worker
        exclude = ['appointments']


class WorkerDetailForm(ModelForm):
    class Meta:
        model = Worker
        fields = '__all__'


class WorkerEditForm(ModelForm):
    class Meta:
        model = Worker
        fields = '__all__'


class AppointmentDetailForm(ModelForm):
    class Meta:
        model = Appointment
        fields = '__all__'

    datetime_when = forms.DateTimeField(label='Appointment on (YYYY-MM-DD HH:MM)',
                                        widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
                                        )


class AppointmentEditForm(ModelForm):
    class Meta:
        model = Appointment
        fields = '__all__'

    datetime_when = forms.DateTimeField(label='Appointment on (YYYY-MM-DD HH:MM)',
                                        widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
                                        )

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        if user is None:
            raise TypeError("User not defined")
        self.user = Worker.get_by_user(user)
        if self.user is None:
            raise TypeError("Worker not defined for: " + user.username)

        super(ModelForm, self).__init__(*args, **kwargs)

    def clean_location(self):
        location = self.cleaned_data['location']
        if self.user.locations.filter(id=location.id).count() == 0:
            self.add_error('location', "You cannot create appointment for this location")
        else:
            return location


class AppointmentAddForm(ModelForm):
    class Meta:
        model = Appointment
        exclude = ['status']

    datetime_when = forms.DateTimeField(label='Appointment on (YYYY-MM-DD HH:MM)',
                                        widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
                                        )

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        if user is None:
            raise TypeError("User not defined")
        self.user = Worker.get_by_user(user)
        if self.user is None:
            raise TypeError("Worker not defined for: " + user.username)

        super(ModelForm, self).__init__(*args, **kwargs)

    def clean_location(self):
        location = self.cleaned_data['location']
        if self.user.locations.filter(id=location.id).count() == 0:
            self.add_error('location', "You cannot create appointment for this location")
        else:
            return location


class VisitDetailForm(ModelForm):
    datetime_begin = forms.DateField(label="Visit begins on",
                                     widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d")
                                     )
    datetime_end = forms.DateField(label="Visit ends on",
                                   widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d")
                                   )

    post_mail_sent = forms.RadioSelect()

    class Meta:
        model = Visit
        exclude = ['is_finished']


class VisitAddForm(ModelForm):
    subject = forms.ModelChoiceField(queryset=Subject.objects.order_by('last_name', 'first_name'))
    datetime_begin = forms.DateField(label="Visit begins on",
                                     widget=forms.TextInput(attrs=DATEPICKER_DATE_ATTRS)
                                     )
    datetime_end = forms.DateField(label="Visit ends on",
                                   widget=forms.TextInput(attrs=DATEPICKER_DATE_ATTRS)
                                   )

    class Meta:
        model = Visit
        exclude = ['is_finished']

    def clean(self):
        if self.cleaned_data['datetime_begin'] >= self.cleaned_data['datetime_end']:
            self.add_error('datetime_begin', "Start date must be before end date")
            self.add_error('datetime_end', "Start date must be before end date")


class KitRequestForm(Form):
    start_date = forms.DateField(label="From date",
                                 widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
                                 required=False
                                 )

    end_date = forms.DateField(label="End date",
                               widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
                               required=False
                               )