import sform

from django.conf import settings
from django.utils.functional import cached_property

from intranet.femida.src.api.core.forms import (
    PG_MAX_INTEGER_VALUE,
    EMPTY_LABEL,
    PositiveIntegerField,
    BooleanField,
    AttachmentMultipleSuggestField,
)
from intranet.femida.src.api.core.validators import validate_phone, validate_birthday
from intranet.femida.src.api.offers.base_forms import (
    OFFER_DATE_INPUT_FORMATS,
    UsernameField,
    NameValidationFormMixin,
    BankDetailsFormMixin,
)
from intranet.femida.src.offers.choices import GENDER, CITIZENSHIP, OFFER_NEWHIRE_STATUSES
from intranet.femida.src.offers.login.validators import LoginValidator
from intranet.femida.src.staff.models import Organization


class PreprofileForm(sform.SForm):

    id = PositiveIntegerField(
        max_value=PG_MAX_INTEGER_VALUE,
        state=sform.REQUIRED,
    )


class PreprofileAcceptForm(NameValidationFormMixin, BankDetailsFormMixin, sform.SForm):
    """
    Внешняя форма анкеты кандидата для Наниматора
    """
    last_name = sform.CharField(max_length=100, state=sform.REQUIRED)
    first_name = sform.CharField(max_length=50, state=sform.REQUIRED)
    middle_name = sform.CharField(max_length=50)
    last_name_en = sform.CharField(max_length=100, state=sform.REQUIRED)
    first_name_en = sform.CharField(max_length=50, state=sform.REQUIRED)
    gender = sform.ChoiceField(choices=GENDER, state=sform.REQUIRED)
    birthday = sform.DateField(
        state=sform.REQUIRED,
        input_formats=OFFER_DATE_INPUT_FORMATS,
        validators=[validate_birthday],
    )
    citizenship = sform.ChoiceField(
        choices=CITIZENSHIP,
        state=sform.REQUIRED,
        empty_label=EMPTY_LABEL,
    )
    residence_address = sform.CharField(max_length=1024, state=sform.REQUIRED)
    home_email = sform.EmailField(max_length=50, state=sform.REQUIRED)
    phone = sform.CharField(
        max_length=50,
        state=sform.REQUIRED,
        validators=[validate_phone],
    )

    username = UsernameField(state=sform.REQUIRED)
    join_at = sform.DateField(state=sform.REQUIRED, input_formats=OFFER_DATE_INPUT_FORMATS)
    comment = sform.CharField()
    is_agree = BooleanField(state=sform.REQUIRED)

    photo = AttachmentMultipleSuggestField(max_files=1)
    passport_pages = AttachmentMultipleSuggestField(max_files=settings.OFFER_MAX_ATTACHMENTS_COUNT)
    snils = AttachmentMultipleSuggestField(max_files=1)
    is_eds_needed = BooleanField()

    @cached_property
    def preprofile(self):
        return self.context['preprofile']

    @cached_property
    def newhire_data(self):
        return self.context['newhire_data']

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

        # Файлы можно выбирать только из загруженных именно к этому препрофайлу
        attachments_qs = self.preprofile.attachments.all()
        for field_name in self.fields:
            field = self.fields[field_name]
            if isinstance(field, AttachmentMultipleSuggestField):
                field.queryset = attachments_qs

        org = Organization.objects.filter(id=self.newhire_data['org']).first()
        if not (org and org.is_russian):
            self.fields.pop('is_eds_needed')

    def get_field_state(self, name):
        if name == 'username' and self.newhire_data['employee_type'] != OFFER_NEWHIRE_STATUSES.new:
            return sform.READONLY
        return super().get_field_state(name)

    def is_bank_details_needed(self):
        return self.newhire_data['org'] != settings.EXTERNAL_ORGANIZATION_ID

    def clean_username(self, username):
        if username:
            # TODO: если Наниматор поддержит всю валидацию на своей стороне,
            # имеет смысл вызывать только validate_in_newhire
            LoginValidator(
                employee_type=self.newhire_data['employee_type'],
                newhire_id=self.preprofile.id,
            ).validate(username)
        return username


class PreprofileCheckLoginExternalForm(sform.SForm):
    """
    SForm проверки логина (для внешней анкеты)
    """
    username = UsernameField(state=sform.REQUIRED)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.preprofile = self.context['preprofile']
        self.newhire_data = self.context['newhire_data']

    def clean_username(self, username):
        if username:
            # TODO: если Наниматор поддержит всю валидацию на своей стороне,
            # имеет смысл вызывать только validate_in_newhire
            LoginValidator(
                employee_type=self.newhire_data['employee_type'],
                newhire_id=self.preprofile.id,
            ).validate(username)
        return username
