from datetime import date, timedelta

from django.forms import ValidationError
from django.conf import settings

import re
import sform

from staff.lib.forms.staff_form import StaffForm
from staff.lib.forms.staff_fields import StaffChoiceField, StaffDateField

from staff.person.models import Staff
from staff.lib.utils.ordered_choices import OrderedChoices

from staff.dismissal.models import (
    INITIATOR,
    IMPRESSION,
    DELETE_FROM_SEARCH,
    DISMISSAL_STATUS,
    REHIRE_RECOMMENDATION,
)


FILTER_TYPES = OrderedChoices(
    ('DOESNOTMATTER',),
    ('TODAY',),
    ('TOMORROW',),
    ('FROMTO',),
)

status_choices = DISMISSAL_STATUS.choices(
    select=('IN_PROGRESS', 'DATE_PASSED', 'CHIT_NOT_COMPLETE', 'DONE', 'NEW')
)
rr_empty_label = '-'
rr_empty_value = ''
rehire_recommendation_choices = REHIRE_RECOMMENDATION.choices(
    include_empty=True, empty_label=rr_empty_label
)


class FilterDismissalsForm(StaffForm):
    status = StaffChoiceField(
        choices=status_choices, empty_label='ALL_REQUESTS', required=False
    )
    filter_type = StaffChoiceField(choices=FILTER_TYPES, required=True)
    date_from = StaffDateField(
        required=False,
        input_formats=tuple(StaffDateField.input_formats) + ('%d.%m.%Y',),
    )
    date_to = StaffDateField(
        required=False,
        input_formats=tuple(StaffDateField.input_formats) + ('%d.%m.%Y',),
    )

    def clean(self):
        cd = self.cleaned_data
        filter_type = cd['filter_type']

        today = date.today()
        tomorrow = today + timedelta(days=1)

        dates = {
            FILTER_TYPES.DOESNOTMATTER: {},
            FILTER_TYPES.TODAY: {
                'date_from': today,
                'date_to': today,
            },
            FILTER_TYPES.TOMORROW: {
                'date_from': tomorrow,
                'date_to': tomorrow,
            },
            FILTER_TYPES.FROMTO: {
                'date_from': cd['date_from'],
                'date_to': cd['date_to'],
            },
        }.get(filter_type)

        cd.update(dates)
        return cd


class DismissalForm(sform.SForm):
    @staticmethod
    def default_getter(name):
        def getter(initial):
            value = getattr(initial['dismissal'], name)
            if name in ('forward_correspondence_to', 'give_files_to'):
                value = value.id
            if name == 'deadline' and not value:
                value = initial['dismissal'].quit_date
            return value
        return getter

    ticket_pattern = re.compile(r'^%s/SALARY-\d+$' % settings.STARTREK_URL)

    def __init__(self, *args, **kwargs):
        super(DismissalForm, self).__init__(*args, **kwargs)
        if not self.initial['can_see_hr_note']:
            del self.fields['note']
        if not self.initial['can_set_deadline']:
            del self.fields['move_to_ext']
            del self.fields['move_to_ext_issue']
            del self.fields['deadline']

    quit_date = sform.DateField(state=sform.REQUIRED)

    forward_correspondence_to = sform.SuggestField(
        queryset=Staff.objects.filter(is_dismissed=False, is_robot=False),
        label_fields=('first_name', 'last_name'),
    )
    give_files_to = sform.SuggestField(
        queryset=Staff.objects.filter(is_dismissed=False, is_robot=False),
        label_fields=('first_name', 'last_name'),
    )

    deadline = sform.DateField(state=sform.REQUIRED)
    move_to_ext = sform.BooleanField()
    move_to_ext_issue = sform.CharField(max_length=512)

    note = sform.CharField()
    delete_email_address = sform.BooleanField()
    delete_correspondence = sform.BooleanField()
    delete_files = sform.BooleanField()
    keep_files = sform.BooleanField()
    initiator = sform.ChoiceField(choices=INITIATOR, state=sform.REQUIRED)
    need_hr_help = sform.BooleanField()
    reason = sform.CharField(max_length=512, state=sform.REQUIRED)
    new_employer = sform.CharField(max_length=512)
    impression = sform.ChoiceField(choices=IMPRESSION, state=sform.REQUIRED)
    rehire_recommendation = sform.ChoiceField(choices=rehire_recommendation_choices)
    delete_from_search = sform.ChoiceField(choices=DELETE_FROM_SEARCH)
    comment = sform.CharField(max_length=512)

    def get_field_state(self, name):

        fields = 'quit_date', 'reason', 'note', 'move_to_ext', 'move_to_ext_issue', 'deadline'
        if self.initial['is_completed'] and name in fields:
            return sform.READONLY

        if name == 'move_to_ext_issue' and self.cleaned_data.get('move_to_ext'):
            return sform.REQUIRED

        return super(DismissalForm, self).get_field_state(name=name)

    def clean_move_to_ext_issue(self, issue):
        cd = self.cleaned_data
        if cd['move_to_ext'] and not self.ticket_pattern.match(issue):
            raise ValidationError('Issue is not st url', code='invalid')
        return issue
