from collections import defaultdict
from datetime import timedelta

from django.contrib.auth import get_user_model
from django.utils import timezone

from intranet.femida.src.candidates.models import DuplicationCase
from intranet.femida.src.candidates.choices import (
    DUPLICATION_CASE_STATUSES,
    CANDIDATE_STATUSES,
)
from intranet.femida.src.stats.fetchers.base import HierarchicReportDataFetcher
from intranet.femida.src.stats import choices, enums
from intranet.femida.src.stats.utils import StaffUnit


User = get_user_model()


class DuplicationCasesQueueDataFetcher(HierarchicReportDataFetcher):

    def initialize_result(self):
        self.result = defaultdict(lambda: {m: set() for m in self.measures})

    def _get_usernames(self, instance):
        """
        Получаем юзеров, связанных c duplication case, которых будем учитывать в статистике
        """
        usernames = set()
        if instance.first_candidate.status == CANDIDATE_STATUSES.in_progress:
            for responsible in instance.first_candidate.responsibles.all():
                usernames.add(responsible.username)
        if instance.second_candidate.status == CANDIDATE_STATUSES.in_progress:
            for responsible in instance.second_candidate.responsibles.all():
                usernames.add(responsible.username)
        return usernames

    def _get_lifetime(self, dt):
        now = timezone.now()
        if dt > now - timedelta(days=1):
            return choices.TIMESLOTS.less_than_1_day
        elif dt > now - timedelta(days=3):
            return choices.TIMESLOTS.between_1_and_3_days
        elif dt > now - timedelta(days=7):
            return choices.TIMESLOTS.between_3_and_7_days
        else:
            return choices.TIMESLOTS.more_than_7_days

    def get_transformed_measures(self, key):
        return {
            'count': len(self.result[key]['count'])
        }

    def collect_data(self):
        duplication_cases = (
            DuplicationCase.unsafe
            .filter(status=DUPLICATION_CASE_STATUSES.new)
            .prefetch_related(
                'first_candidate__responsibles',
                'second_candidate__responsibles',
            )
        )
        for dc in duplication_cases:
            usernames = self._get_usernames(dc)
            lifetime = self._get_lifetime(dc.created)
            if usernames:
                keys = []
                for username in usernames:
                    keys.extend(self.get_related_keys((
                        StaffUnit(username, enums.StaffUnitTypes.user),
                        lifetime,
                    )))
            else:
                keys = self.get_related_keys((
                    StaffUnit(enums.StatKeys.unknown_department, enums.StaffUnitTypes.department),
                    lifetime,
                ))

            for key in keys:
                self.result[key]['count'].add(dc.id)
