from staff.budget_position.workflow_service import entities


class GetSchemeDetails:
    def __init__(
        self,
        schemes_calculator: entities.SchemesCalculator,
        grade_calculator: entities.GradeCalculator,
        staff_service: entities.StaffService,
        oebs_service: entities.OEBSService,
    ):
        self._schemes_calculator = schemes_calculator
        self._grade_calcualtor = grade_calculator
        self._staff_service = staff_service
        self._oebs_service = oebs_service

    def get_bonus_scheme(self, request: entities.GetSchemeRequest) -> entities.BonusSchemeDetails or None:
        occupation_groups = self._staff_service.occupation_details(request.occupation_id)
        bonus_scheme_id = self._schemes_calculator.bonus_scheme_id(
            bonus_group=occupation_groups.bonus_group,
            grade_level=request.grade_level,
            department_id=request.department_id,
            occupation_id=request.occupation_id,
        )

        if not bonus_scheme_id:
            return None

        return self._schemes_calculator.bonus_scheme_details(bonus_scheme_id)

    def get_review_scheme(self, request: entities.GetSchemeRequest) -> entities.ReviewSchemeDetails or None:
        occupation_groups = self._staff_service.occupation_details(request.occupation_id)
        review_scheme_id = self._schemes_calculator.review_scheme_id(
            department_id=request.department_id,
            occupation_id=request.occupation_id,
            review_group=occupation_groups.review_group,
            grade_level=request.grade_level,
        )

        if not review_scheme_id:
            return None

        return self._schemes_calculator.review_scheme_details(review_scheme_id)

    def get_reward_scheme(self, request: entities.GetSchemeRequest) -> entities.RewardSchemeDetails or None:
        occupation_groups = self._staff_service.occupation_details(request.occupation_id)
        assert request.grade_level is not None or request.femida_professional_level is not None

        grade_level = request.grade_level
        if request.grade_level is None:
            _, grade_level = self._grade_calcualtor.grade_by_prof_level(
                request.occupation_id,
                request.femida_professional_level,
            )

        reward_scheme_id = self._schemes_calculator.reward_scheme_id(
            reward_group=occupation_groups.reward_group,
            grade_level=grade_level,
            department_id=request.department_id,
            is_internship=request.is_internship,
        )

        if not reward_scheme_id:
            return None

        scheme_details = self._schemes_calculator.reward_scheme_details(reward_scheme_id)

        if not scheme_details:
            return None

        insurance_calculator = entities.InsuranceCalculator(scheme_details, request)
        scheme_details.has_health_insurance = insurance_calculator.has_health_insurance()
        scheme_details.has_life_insurance = insurance_calculator.has_life_insurance()
        scheme_details.has_food_compensation = scheme_details.food not in ('Без питания', 'Не определено')
        return scheme_details

    def get_current_reward_category(self, budget_position_code: entities.BudgetPositionCode) -> str or None:
        existing_bp_info = self._oebs_service.get_position_as_change(budget_position_code)
        existing_bp_scheme_details = self._staff_service.reward_scheme_details(existing_bp_info.reward_scheme_id)

        if not existing_bp_scheme_details:
            return None

        return existing_bp_scheme_details.category
