from collections import defaultdict
from datetime import date
from typing import Dict

from staff.departments.controllers.intern_transfer_detector import InternTransferDetector
from staff.departments.controllers.actions.person_action import PersonAction

from staff.proposal.hr_deadlines.split_data import SplitData


class DeadlineMatcher:
    def __init__(self, intern_transfer_detector: InternTransferDetector = None):
        self._intern_transfer_detector = intern_transfer_detector or InternTransferDetector()

    def correct_application_dates(
        self,
        action: PersonAction,
        date_to_change: Dict[date, Dict],
        split_data: SplitData,
    ) -> Dict[date, Dict]:
        if (
            action.department.from_maternity_leave
            or self._intern_transfer_detector.is_intern_transfer_to_staff(action)
            or (
                action.has_salary_change()
                and action.salary.old_rate != action.salary.new_rate
                and not self._is_full_rate_changed(action.salary)
            )
        ):
            max_search = split_data.desired_date
        else:
            max_search = date(split_data.desired_date.year, split_data.desired_date.month, 1)

        replaced_date_to_change = defaultdict(dict)
        for border_date, info in date_to_change.items():
            replaced_date_to_change[max(border_date, max_search)].update(info)
        return replaced_date_to_change

    def get_salary_date(self, action: PersonAction, split_data: SplitData) -> date:
        salary = action.salary

        if salary.old_wage_system != salary.new_wage_system:
            return split_data.salary_date

        if salary.old_currency != salary.new_currency:
            return split_data.salary_date

        if self._is_full_rate_changed(salary):
            return split_data.salary_date

        return self.get_pieceworker_date(action.login, split_data, split_data.table_date)

    @staticmethod
    def get_pieceworker_date(login: str, split_data: SplitData, target_date: date) -> date:
        # сдельная? надо написать
        if split_data.login_to_paysys[login] == 'XXYA_JOBPRICE':
            return split_data.deal_date
        return target_date

    @staticmethod
    def _is_full_rate_changed(salary):
        old_full_rate = float(salary.old_salary or "0") / float(salary.old_rate or "1")
        new_full_rate = float(salary.new_salary or "0") / float(salary.new_rate or "1")

        return old_full_rate != new_full_rate
