from django.contrib.auth import get_user_model
from django.db.models import F
from django.utils import timezone

from rest_framework import status
from rest_framework.response import Response

from intranet.femida.src.actionlog.decorators import action_logged
from intranet.femida.src.api.core.views import BaseView
from intranet.femida.src.core.shortcuts import get_object_or_40x
from intranet.femida.src.core.db.helpers import get_count_subquery
from intranet.femida.src.interviews.models import Interview
from intranet.femida.src.problems.models import Problem
from intranet.femida.src.users.utils import filter_users_by_aa_type
from intranet.femida.src.utils.datetime import shifted_now
from intranet.femida.src.vacancies.choices import VACANCY_ROLES

from .forms import InterviewerListFilterForm
from .serializers import InterviewerSerializer, UserWithDepartmentSerializer


User = get_user_model()


def get_interviews_count_subquery(**filter_params):
    return get_count_subquery(
        queryset=Interview.unsafe.alive().filter(**filter_params),
        reverse_related_name='interviewer',
    )


class FavoriteProblemView(BaseView):

    @action_logged('problem_fan_add')
    def put(self, request, *args, **kwargs):
        """
        Добавление любимой задачи
        """
        problem = get_object_or_40x(
            Problem.alive_objects.all(),
            pk=kwargs.get('pk'),
        )
        problem.fans.add(request.user)
        return Response({}, status.HTTP_204_NO_CONTENT)

    @action_logged('problem_fan_remove')
    def delete(self, request, *args, **kwargs):
        """
        Удаление задачи из списка любимых
        """
        problem = get_object_or_40x(
            Problem.alive_objects.all(),
            pk=kwargs.get('pk'),
        )
        problem.fans.remove(request.user)
        return Response({}, status.HTTP_204_NO_CONTENT)


class UserListView(BaseView):

    model_class = User
    list_item_serializer_class = UserWithDepartmentSerializer

    def filter_queryset(self, queryset):
        queryset = queryset.filter(is_dismissed=False).select_related('department')
        aa_type = self.request.query_params.get('aa_type')
        if aa_type:
            queryset = filter_users_by_aa_type(queryset, aa_type)
        return queryset.order_by('username')

    def get(self, *args, **kwargs):
        return self.list(*args, **kwargs)


class InterviewerListView(BaseView):

    model_class = User
    list_item_serializer_class = InterviewerSerializer

    def filter_queryset(self, queryset):
        filter_form = InterviewerListFilterForm(data=self.request.query_params)
        self.validate(filter_form)
        filter_params = filter_form.cleaned_data

        queryset = queryset.filter(is_dismissed=False)
        if filter_params['user']:
            queryset = queryset.filter(username=filter_params['user'].username)
        elif filter_params['aa_type']:
            queryset = filter_users_by_aa_type(queryset, filter_params['aa_type'])
        elif filter_params['vacancy']:
            queryset = queryset.filter(
                vacancy_memberships__vacancy_id=filter_params['vacancy'],
                vacancy_memberships__role=VACANCY_ROLES.interviewer,
            )

        queryset = self._annotate_with_interviews_count(queryset)
        return queryset.order_by('interviews_total_count')

    def _annotate_with_interviews_count(self, queryset):
        return queryset.annotate(
            interviews_finished_2weeks_count=get_interviews_count_subquery(
                finished__gte=shifted_now(days=-14),
            ),
            interviews_planned_count=get_interviews_count_subquery(
                event_start_time__gte=timezone.now(),
            ),
            interviews_total_count=(
                F('interviews_finished_2weeks_count') + F('interviews_planned_count')
            ),
        )

    def get(self, *args, **kwargs):
        return self.list(*args, **kwargs)
