from django.shortcuts import get_object_or_404
from django.db.models import Q
from numpy import True_
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from ..models import Decision, DecisionChoices, Notation, Poste
from ..paginations import HeavyDataPagination
from ..serializers.notation import NotationSerializer
from .commun import (GestionnairePermission, execution_time_viewset,
                     query_count_viewset)


@execution_time_viewset
@query_count_viewset
class NotationView(ModelViewSet):
    """
    Cette classe est dédiée au vue des notations.
    """
    permission_classes = [IsAuthenticated, GestionnairePermission]
    serializer_class = NotationSerializer
    queryset = Notation.objects.all()
    pagination_class = HeavyDataPagination

    def list(self, request: Request, pk=None) -> Response:
        """La fonction list envoie le classement des postes pour un administré particulier et inversement.

        :type request: rest_framework.request.Request
        :param request: Request contenant l'administre ou le poste.

        :return:    - **JsonResponse** (*JsonResponse*): Json contenant le classement.
        """
        notations_list = []
        counter = 10
        if 'administre_id' in request.query_params:
            q = 'poste_pam'
            q1 = 'poste'
            administre_id = request.query_params['administre_id']
            administres_keys = (
                'poste_pam__id',
                'poste_pam__poste__p_id',
                'poste_pam__poste__p_nf',
                'poste_pam__poste__p_domaine',
                'poste_pam__poste__p_filiere',
                'poste_pam__poste__p_eip',
                'poste_pam__poste__formation_emploi__fe_code',
                'poste_pam__poste__p_notes_gestionnaire',
                'poste_pam__poste__p_liste_id_marques',
                'poste_pam__poste__p_code_fonction',
                'poste_pam__p_avis_pam',
                'poste_pam__poste__p_dep',
                'poste_pam__poste__formation_emploi__fe_libelle',
                'poste_pam__poste__p_fonction',
                'poste_pam__poste__formation_emploi__fe_garnison_lieu',
                'poste_pam__poste__formation_emploi__fe_code_postal',
                'no_score_administre',
                'no_flag_cple_ideal')

            notation_qs = (Notation.objects.filter(Q(administre_pam_id=administre_id) & Q(poste_pam__decisions__isnull=True))
                                        .order_by('-no_score_administre')
                                        .select_related('poste_pams'))

            notation_qs_matching_parfait = (Notation.objects.filter(administre_pam_id=administre_id,
                                                                    no_flag_cple_ideal=True,
                                                                    poste_pam__decisions__isnull=True)
                                                            .select_related('poste_pams'))

            notation_qs.union(notation_qs_matching_parfait)
            notation_qs = notation_qs | notation_qs_matching_parfait
            notations_list = list(notation_qs.values(*administres_keys))

            for notation in notations_list:
                poste_id = notation['poste_pam__id']
                topCounter = 0
                allNotationsInvolved = Notation.objects.filter(poste_pam_id=poste_id)
                for note in allNotationsInvolved:
                    topList = list(
                        Notation.objects.filter(no_id=note.no_id).order_by('-no_score_administre').values('poste_pam_id'))
                    topPostes = [poste['poste_pam_id'] for poste in topList]
                    if poste_id in topPostes:
                        topCounter += 1

                notation['poste__nb_top'] = topCounter

        if 'poste_id' in request.query_params:
            q = "administre_pam"
            q1 = 'administre'
            poste_id = request.query_params['poste_id']
            postes_keys = (
                'administre_pam__id',
                'administre_pam__administre__a_id_sap',
                'administre_pam__administre__a_nom',
                'administre_pam__administre__a_prenom',
                'administre_pam__a_statut_pam_annee',
                'administre_pam__administre__grade_id',
                'administre_pam__administre__a_liste_id_marques',
                'administre_pam__decision__de_decision',
                'administre_pam__decision__de_date_decision',
                'no_score_administre',
                'no_flag_cple_ideal',
                'administre_pam__notes_pam',
                'administre_pam__administre__a_notes_gestionnaire',
                'administre_pam__administre__a_fonction',
                'administre_pam__administre__a_code_fonction',
                'administre_pam__administre__a_liste_id_marques',
                'administre_pam__decision__poste_id')
            
            notation_qs = (Notation.objects.filter(Q(poste_pam_id=poste_id) & Q(administre_pam__decision__isnull=True))
                                        .order_by('-no_score_administre')
                                        .select_related('administre_pam'))
            notation_qs_matching_parfait = (Notation.objects.filter(poste_pam_id=poste_id,
                                                                    no_flag_cple_ideal=True,
                                                                    administre_pam__decision__isnull=True)
                                                            .select_related('administre_pam'))
            notation_qs.union(notation_qs_matching_parfait)
            notations_list = list(
                notation_qs.values(*postes_keys))

            for notation in notations_list:
                administre_id = notation['administre_pam__id']
                topCounter = 0
                allNotationsInvolved = Notation.objects.filter(administre_pam_id=administre_id)
                for note in allNotationsInvolved:
                    topList = list(Notation.objects.filter(no_id=note.no_id)
                                                .order_by('-no_score_administre')
                                                .values('administre_pam_id'))
                    topAdministres = [administre['administre_pam_id'] for administre in topList]
                    if administre_id in topAdministres:
                        topCounter += 1

                notation['administre__nb_top'] = topCounter

        result = []
        for notation in notations_list:
            res_notation = {q1: {}}
            for key in notation:
                if (q + "__") in key:
                    res_notation[q1][key.replace(q + '__', '').replace(q1 + '__', '')] = notation[key]
                else:
                    res_notation[key] = notation[key]
            result.append(res_notation)

        
        return Response(result)
