import sform

from django.core.exceptions import ValidationError

from staff.budget_position.const import FemidaProfessionalLevel
from staff.departments.models import Department
from staff.person.models import Occupation


class GetBonusSchemeForm(sform.SForm):
    department = sform.ModelChoiceField(
        queryset=Department.objects.all(),
        label_extractor='id',
        state=sform.REQUIRED,
    )
    grade_level = sform.IntegerField(state=sform.REQUIRED)
    occupation = sform.ModelChoiceField(
        queryset=Occupation.objects.all(),
        label_extractor='name',
        state=sform.REQUIRED,
    )


class GetReviewSchemeForm(sform.SForm):
    department = sform.ModelChoiceField(
        queryset=Department.objects.all(),
        label_extractor='id',
        state=sform.REQUIRED,
    )
    grade_level = sform.IntegerField(state=sform.REQUIRED)
    occupation = sform.ModelChoiceField(
        queryset=Occupation.objects.all(),
        label_extractor='name',
        state=sform.REQUIRED,
    )


class GetRewardSchemeForm(sform.SForm):
    department = sform.ModelChoiceField(
        queryset=Department.objects.all(),
        label_extractor='id',
        state=sform.REQUIRED,
    )
    grade_level = sform.IntegerField(state=sform.NORMAL)
    occupation = sform.ModelChoiceField(
        queryset=Occupation.objects.all(),
        label_extractor='name',
        state=sform.REQUIRED,
    )
    budget_position_code = sform.IntegerField(state=sform.NORMAL)
    is_internship = sform.NullBooleanField()
    professional_level = sform.ChoiceField(
        choices=FemidaProfessionalLevel.choices(),
        state=sform.NORMAL,
    )
    is_main_work_place = sform.NullBooleanField()
    contract_term = sform.IntegerField(state=sform.NORMAL)
    contract_term_date = sform.DateField(state=sform.NORMAL)

    @staticmethod
    def clean_professional_level(value: str) -> FemidaProfessionalLevel or None:
        if not value:
            return None
        return FemidaProfessionalLevel(int(value))

    def clean(self):
        cleaned_data = super().clean()
        if not cleaned_data.get('grade_level') and not cleaned_data.get('professional_level'):
            raise ValidationError('You should provide grade_level or professional_level', code='required')

        return cleaned_data
