from rest_framework import serializers

from intranet.femida.src.offers.choices import CONTRACT_TYPES
from intranet.femida.src.offers.models import Offer
from intranet.femida.src.staff.choices import BP_REGISTRY_REQUEST_TYPE
from intranet.femida.src.vacancies.choices import VACANCY_REPLACEMENT_REASONS


OEBS_PROBATION_PERIOD_CODES_MAP = {
    '0w': 10,
    '0m': 10,
    '2w': 20,
    '3m': 30,
    '6m': 40,
}


class BPRegistryOfferSerializer(serializers.ModelSerializer):
    """
    Сериализатор оффера для отправки в реестр БП
    """
    budget_position_id = serializers.ReadOnlyField(source='vacancy.budget_position_id')
    vacancy_name = serializers.ReadOnlyField(source='vacancy.name')
    job_issue_key = serializers.ReadOnlyField(source='vacancy.startrek_key')
    hr_product_id = serializers.ReadOnlyField(source='vacancy.value_stream.oebs_product_id')
    salary_issue_key = serializers.ReadOnlyField(source='startrek_salary_key')

    offer = serializers.ReadOnlyField(source='id')
    organization = serializers.ReadOnlyField(source='org_id')
    currency = serializers.ReadOnlyField(source='payment_currency.code')
    profession = serializers.ReadOnlyField(source='profession.startrek_id')
    profession_key = serializers.ReadOnlyField(source='profession.staff_id')
    request_type = serializers.SerializerMethodField()
    review_scheme = serializers.ReadOnlyField(source='schemes_data.review_scheme_id')
    reward_scheme = serializers.ReadOnlyField(source='schemes_data.reward_scheme_id')
    bonus_scheme = serializers.ReadOnlyField(source='schemes_data.bonus_scheme_id')

    def get_request_type(self, obj):
        if obj.is_internal:
            return BP_REGISTRY_REQUEST_TYPE.internal_offer
        return BP_REGISTRY_REQUEST_TYPE.offer

    class Meta:
        model = Offer
        fields = (
            'budget_position_id',
            'username',
            'vacancy',
            'vacancy_name',
            'job_issue_key',
            'hr_product_id',
            'salary_issue_key',
            'profession',
            'profession_key',
            'department',
            'abc_services',
            'payment_type',

            'offer',
            'grade',
            'office',
            'organization',
            'salary',
            'currency',
            'work_hours_weekly',

            'request_type',
            'review_scheme',
            'reward_scheme',
            'bonus_scheme',
            'is_internship',
        )


class BPRegistryOfferRejectionSerializer(serializers.ModelSerializer):
    """
    Сериализатор для отправки отказа от оффера в реестр БП
    """
    budget_position_id = serializers.ReadOnlyField(source='vacancy.budget_position_id')
    job_issue_key = serializers.ReadOnlyField(source='vacancy.startrek_key')
    offer = serializers.ReadOnlyField(source='id')
    department = serializers.ReadOnlyField(source='vacancy.department_id')

    request_type = serializers.SerializerMethodField()

    def get_request_type(self, obj):
        return BP_REGISTRY_REQUEST_TYPE.offer_rejection

    class Meta:
        model = Offer
        fields = (
            'budget_position_id',
            'department',
            'job_issue_key',
            'offer',
            'vacancy',
            'request_type',
        )


class BPAssignmentOfferSerializer(serializers.ModelSerializer):
    """
    Сериализатор оффера для создания назначения через Реестр
    """
    person = serializers.ReadOnlyField(source='oebs_person_id')
    budget_position_id = serializers.ReadOnlyField(source='vacancy.budget_position_id')
    organization = serializers.ReadOnlyField(source='org_id')
    currency = serializers.ReadOnlyField(source='payment_currency.code')
    probation_period = serializers.SerializerMethodField()
    position = serializers.ReadOnlyField(source='position.staff_id')
    is_replacement = serializers.SerializerMethodField()
    instead_of = serializers.SerializerMethodField()

    def get_probation_period(self, obj):
        if obj.probation_period:
            probation_period_code = f'{obj.probation_period}{obj.probation_period_unit[0]}'
            return OEBS_PROBATION_PERIOD_CODES_MAP.get(probation_period_code)

    def get_is_replacement(self, obj):
        return obj.contract_type == CONTRACT_TYPES.temp_replacement

    def get_instead_of(self, obj):
        # Замена по увольнению/ротации - это для OEBS обычный найм без связки с уходящим сотрудником
        if obj.vacancy.replacement_reason == VACANCY_REPLACEMENT_REASONS.maternity_leave:
            return obj.vacancy.instead_of and obj.vacancy.instead_of.username

    class Meta:
        model = Offer
        fields = (
            'person',
            'budget_position_id',
            'organization',
            'department',
            'position',
            'office',
            'employment_type',
            'contract_term_date',
            'contract_term',
            'payment_type',
            'currency',  # Я.Найм примет любую валюту. Не RUB будет красить ошибочной
            'salary',
            'hourly_rate',
            'other_payments',
            'join_at',
            'probation_period',
            'is_replacement',
            'instead_of',
        )
