from functools import reduce
from urllib import request

from django import template
import datetime
import operator
import random

from BasicData.custom_fonctions import calcTime, get_horaire_split, get_next_or_prev
from BasicData.models import Note, SyllabusEcue, Enseignant, Reclamations, EnseignantUfr, Etudiant, Evaluation, Ue, \
    Ecue, Annee, Deliberation, DeliberationUe, EmploiDuTemps2, SeanceCours, EnseignantUe, NiveauEtudiant, Ufr, \
    InactiveUe, Document, ReponseDemandeActes, Reinscription, User, Semestre, ParcoursSemestre, Compensation, FlashInfo,Diffusion,DemandeActes,\
    PsCours,PsPublication,PsPJoint,PersonnelService,Personnel

# déclarations de la librairie
from django.db.models import Sum

#from BasicData.templatetags.custom_tag import get_credit_ue
#from BasicData.templatetags.custom_tag import get_etudiant_session_2_moy_ue

register = template.Library()
# -----------------

# TODO: Today date
y = datetime.datetime.now().year
m = datetime.datetime.now().month
d = datetime.datetime.now().day
date = str(d) + "-" + str(m) + "-" + str(y)


#TODO: GET ECUE BY UFR AND SEMESTRE
@register.filter(name='get_ecue_by_ufr_and_semestre')
def get_ecue_by_ufr_and_semestre(ufr_id,semestre_id):
    ECUE = Ecue.objects.filter(ue__ufr__id=ufr_id,ue__semestre__id=semestre_id,active=True).order_by('libelle')
    return ECUE


#TODO: GET ECUE BY UE
@register.filter(name='get_ecue_by_ue')
def get_ecue_by_ue(ue_id):
    ECUE = Ecue.objects.filter(ue__id=ue_id,active=True).order_by('libelle')
    return ECUE

####################### UE ##################################
#TODO: GET UE BY UFR AND SEMESTRE
@register.filter(name='get_ue_by_ufr_and_semestre')
def get_ue_by_ufr_and_semestre(ufr_id,semestre_id):
    UE = Ue.objects.filter(ufr__id=ufr_id,semestre__id=semestre_id,).order_by('libelle')
    return UE

#TODO: GET UE BY UFR AND SEMESTRE SET
@register.filter(name='get_ue_by_ufr_and_semestre_set')
def get_ue_by_ufr_and_semestre_set(args,semestre_id):
    ufr_id=args[0]
    annee=args[1]
    InUe = [Ue.objects.get(id=ue['ue__id']) for ue in InactiveUe.objects.filter(ue__ufr__id=ufr_id,annee__id=annee).values('ue__id').distinct()]
    UES = Ue.objects.filter(ufr__id=ufr_id,semestre__id=semestre_id,active=True).order_by('libelle')
    UE =[]
    for ue in UES:
        if ue in InUe:
            pass
        else:
            UE.append(ue)
    return UE


#TODO: GET UE BY UFR SET
@register.filter(name='get_ue_by_ufr_set')
def get_ue_by_ufr_set(ufr_id,annee,niveau):
    InUe = [Ue.objects.get(id=ue['ue__id']) for ue in
            InactiveUe.objects.filter(ue__ufr__id=ufr_id, annee__id=annee).values('ue__id').distinct()]
    UES = Ue.objects.filter(ufr__id=ufr_id,active=True,niveau=niveau).order_by('libelle')
    UE =[]
    for ue in UES:
        if ue.id in InUe:
            pass
        else:
            UE.append(ue)
    return UE


#TODO: GET UE BY UFR SET
@register.filter(name='get_ue_by_ufr_simple')
def get_ue_by_ufr_simple(ufr_id,annee):
    InUe = [Ue.objects.get(id=ue['ue__id']) for ue in
            InactiveUe.objects.filter(ue__ufr__id=ufr_id, annee__id=annee).values('ue__id').distinct()]
    UES = Ue.objects.filter(ufr__id=ufr_id,active=True).order_by('libelle')
    UE = []
    for ue in UES:
        if ue.id in InUe:
            pass
        else:
            UE.append(ue)
    return UE


#TODO: GET UE BY UFR SET
@register.filter(name='get_ue_by_ufr_simple2')
def get_ue_by_ufr_simple2(ufr_id,args):
    annee = args[0]
    niveau = args[0]
    InUe = [Ue.objects.get(id=ue['ue__id']) for ue in
            InactiveUe.objects.filter(ue__ufr__id=ufr_id, annee__id=annee).values('ue__id').distinct()]
    UES = Ue.objects.filter(ufr__id=ufr_id,active=True,niveau__id=niveau).order_by('libelle')
    UE = []
    for ue in UES:
        if ue.id in InUe:
            pass
        else:
            UE.append(ue)
    return UE


#TODO: GET UE BY UFR SET
@register.filter(name='get_ecue_by_ufr_simple')
def get_ecue_by_ufr_simple(ufr_id,annee):
    InUe = [Ue.objects.get(id=ue['ue__id']) for ue in
            InactiveUe.objects.filter(ue__ufr__id=ufr_id, annee__id=annee).values('ue__id').distinct()]
    UES = Ue.objects.filter(ufr__id=ufr_id,active=True).order_by('libelle')
    UE =[]
    for ue in UES:
        if ue.id in InUe:
            pass
        else:
            UE.append(ue)

    ecueList = [Ecue.objects.filter(ue=ue) for ue in UE]
    ecues =[]
    if ecueList:
        for ecu in ecueList:
            for ec in ecu:
                ecues.append(ec)

    return ecues


#TODO: GET UE BY UFR SET ALL
@register.filter(name='get_ue_by_ufr_set_all')
def get_ue_by_ufr_set_all(ufr_id):
    InUe = [Ue.objects.get(id=ue['ue__id']) for ue in
            InactiveUe.objects.filter(ue__ufr__id=ufr_id).values('ue__id').distinct()]
    UES = Ue.objects.filter(ufr__id=ufr_id,active=True).order_by('libelle')
    UE =[]
    for ue in UES:
        if ue.id in InUe:
            pass
        else:
            UE.append(ue)
    return UE

##############################################################


#TODO: GET ENSEIGNANT ECUE
@register.filter(name='get_enseignant_ecue')
def get_enseignant_ecue(enseignant,key):
    EnseignantUes = [ecue for ecue in EnseignantUe.objects.filter(annee=Annee.objects.last(), enseignant__id=enseignant).values("ecue__libelle").distinct()]
    if key=='obj':
        return EnseignantUes
    elif key=='length':
        return len(EnseignantUes)


def get_credit_ue(ue):
    # ON RECUPERE LES ECUES DE L'UE
    ecues =  Ecue.objects.filter(ue=ue)

    # ON COMPTABILISE LES CREDITS ECUE
    total_credit = 0
    for ecue in ecues:
        total_credit += ecue.credit

    return total_credit

#TODO: GET UFR UE LIST
@register.filter(name='get_ufr_ue_list')
def get_ufr_ue_list(args,key):
    niveau = args[1]
    ufr = args[2]
    semestre = args[3]
    UES = Ue.objects.filter(niveau__id=niveau,ufr__id=ufr,semestre__id=semestre,active=True)
    total_credit = 0
    if UES:
        for ue in UES:
            total_credit += get_credit_ue(ue)
    if key=='obj':
        return UES
    elif key =='credit':
        return total_credit


#TODO: GET ALL UFR
@register.filter(name='get_all_ufr')
def get_all_ufr(key):
    if key=='all':
        return Ufr.objects.all().order_by('code')
    else:
        return Ufr.objects.filter(id=key).last()

#TODO: GET ANNEE LAST
@register.filter(name='get_annee_last')
def get_annee_last(key):
    if key=='last':
        return Annee.objects.last()
    else:
        return Annee.objects.filter(id=key).last()


#TODO: GET ANNEE LAST
@register.filter(name='check_inscription')
def check_inscription(email):
    nivEt = NiveauEtudiant.objects.filter(annee=Annee.objects.last(),etudiant__email=email).last()
    return nivEt


#TODO: GET ETUDIANT BY ECUE
@register.filter(name='get_ecue_etudiant')
def get_ecue_etudiant(args):
    annee = args[0]
    ufr = args[1]
    niveau = args[2]
    #year = Annee.objects.get(id=annee)

    # ON RECUPERE L'ANNEE PRECEDENTE
    #prevAnnee = get_next_or_prev(year,'prev')

    etudiants = [
        etudiant.etudiant for etudiant in NiveauEtudiant.objects.filter(
            annee__id=annee,
            etudiant__ufr__id=ufr,
            niveau__id=niveau
        ).order_by('etudiant__nom')
    ]
    return etudiants


#TODO: GET PDF ETUDIANT LIST
@register.filter(name='get_etudiant_list')
def get_etudiant_list(args):
    annee = args[0]
    niveau = args[1]
    ufr = args[2]
    etudiants = [etudiant.etudiant for etudiant in NiveauEtudiant.objects.filter(annee__id=annee, niveau__id=niveau, etudiant__ufr__id=ufr).order_by('etudiant__nom')]
    return etudiants


#TODO: GET ETUDIANT BY UFR LIST
@register.filter(name='get_etudiant_by_ufr')
def get_etudiant_by_ufr(ufr,annee):
    etudiants = [etudiant.etudiant for etudiant in NiveauEtudiant.objects.filter(annee__id=annee,etudiant__ufr__id=ufr).order_by('etudiant__nom')]
    return etudiants


@register.filter(name='check_document_add')
def check_document_add(typedoc,etudiant):
    doc = Document.objects.filter(typedoc__id=typedoc,etudiant__id=etudiant).last()
    return doc


@register.filter(name='check_document_valid')
def check_document_valid(typedoc,etudiant):
    doc = Document.objects.filter(typedoc__id=typedoc,etudiant__id=etudiant,valid=True).last()
    return doc


@register.filter(name='get_note_delib_ue')
def get_note_delib_ue(ue,an):
    delibUe = DeliberationUe.objects.filter(ue=ue,annee=an).last()
    note = 0.0
    if delibUe:
        note = delibUe.note
    return note


@register.filter(name='etudiants_inscrits')
def etudiants_inscrits(an,key):
    etudiants = [etud.etudiant for etud in NiveauEtudiant.objects.filter(annee__id=an)]
    if key=='length':
        return len(etudiants)
    elif key=='obj':
        return etudiants
    else:
        pass


@register.filter(name='check_reponse_by_demande')
def check_reponse_by_demande(demande):
    rep = ReponseDemandeActes.objects.filter(demande__id=demande)
    return rep


@register.filter(name='get_credit_semestre_ufr')
def get_credit_semestre_ufr(args,semestre):
    ufr_id = args[0]
    annee = args[1]
    cred = sum([get_credit_ue(ue) for ue in get_ue_by_ufr_and_semestre_set([ufr_id,annee],semestre)])
    return cred


@register.filter(name='get_credit_ufr')
def get_credit_ufr(args,niveau):
    ufr_id = args[0]
    annee = args[1]

    cred = 0
    if niveau:
        cred = sum([get_credit_ue(ue) for ue in get_ue_by_ufr_set(ufr_id,annee,niveau.id)])
    return cred

@register.filter(name='get_credit_ufr_niveau')
def get_credit_ufr_niveau(args,niveau):
    ufr_id = args[0]
    annee = args[1]
    cred = sum([get_credit_ue(ue) for ue in get_ue_by_ufr_set(ufr_id,annee,niveau)])
    return cred


@register.filter(name='get_niveau_etudiant')
def get_niveau_etudiant(etudiant,annee):
    niveaux = NiveauEtudiant.objects.filter(etudiant=etudiant,annee=annee).last()
    if niveaux:
        return niveaux.niveau
    else:
        return None


@register.filter(name='get_semestre_niveau_by_annee')
def get_semestre_niveau_by_annee(etudiant,annee):
    niveau = get_niveau_etudiant(etudiant,annee)
    sem =None
    if niveau:
        sem = Semestre.objects.filter(niveau=niveau).order_by('libelle')
    return sem

@register.filter(name='get_sexe_libelle')
def get_sexe_libelle(sexe,key):
    rt = ''
    if sexe =='M' and key=='MaFe':
        rt = 'Masculin'
    elif sexe =='F' and key=='MaFe':
        rt = 'Féminin'
    else:pass
    return rt



@register.filter(name='check_inscription_etudiant')
def check_inscription_etudiant(etudiant):
    etud = NiveauEtudiant.objects.filter(annee=Annee.objects.last(),etudiant=etudiant).last()
    return etud


@register.filter(name='check_reinscription_etudiant')
def check_reinscription_etudiant(etudiant):
    etud = Reinscription.objects.filter(annee=Annee.objects.last(),etudiant=etudiant).last()
    return etud


@register.filter(name='get_civilite')
def get_civilite(mail):
    user = User.objects.get(email=mail)
    if user.civilite:
        return user.civilite
    else:
        return ''


@register.filter(name='get_enseignat_grade_abrev')
def get_enseignat_grade_abrev(email):
    grade  = Enseignant.objects.get(email=email).grade

    user = User.objects.get(email=email)
    civ = ''
    if user.civilite:
        civ = user.civilite

    abrev = None
    if grade and grade.libelle =='Doctorat':
        abrev = 'Dr'
    elif grade and grade.libelle =='Professeur Titulaire':
        abrev = 'Prof.'
    elif grade and grade.libelle =='Maître de conférence':
        abrev = ''
    elif grade and grade.libelle =='Inspecteur principal':
        abrev = ''
    elif grade and grade.libelle =='Educateur':
        abrev = ''
    elif grade and grade.libelle =='':
        abrev = ''
    elif grade and grade.libelle =='':
        abrev = ''
    elif grade and grade.libelle =='':
        abrev = ''
    elif grade and grade.libelle =='':
        abrev = ''
    else:
        abrev = civ

    return abrev


@register.filter(name='get_parcours')
def get_parcours(ufr,niveau):
    parc = ParcoursSemestre.objects.filter(gradeMentionUfr__ufr=ufr,semestre__niveau=niveau).last()
    if parc:
        return parc.parcours
    else:
        return ''

@register.filter(name='create_list_2_obj')
def create_list_2_obj(obj1,obj2):
    return [obj1,obj2]

@register.filter(name='check_compensation')
def check_compensation(args,ue):
    etudiant = args[0]
    annee = args[1]
    compensation = Compensation.objects.filter(etudiant=etudiant,annee=annee,ue=ue)
    return compensation


@register.filter(name='get_compens_note')
def get_compens_note(args,ue):
    etudiant = args[0]
    annee = args[1]
    compensation = Compensation.objects.filter(etudiant=etudiant,annee=annee,ue=ue).last()
    note = 0.0
    if compensation:
        note = compensation.note
    return note


@register.filter(name='get_salle_dispo')
def get_salle_dispo(args,horaire):
    periode =args[0]
    jour =args[1]
    debut_cours = get_horaire_split(horaire, 'debut')
    return


@register.filter(name='get_edt_enseignant')
def get_edt_enseignant(ecue,annee):
    enseignants = EnseignantUe.objects.filter(ecue=ecue,annee=annee)
    return enseignants


@register.filter(name='get_flash_infos')
def get_flash_infos(mail):
    # ON VERIFIE SI L'UTILISATEUR EST UN ENSEIGNANT OU UN ETUDIANT
    enseignant = Enseignant.objects.filter(email=mail).last()
    etudiant = Etudiant.objects.filter(email=mail).last()

    # ON RECUPERE LES INFOS DES ETUDIANTS
    infos = None
    if etudiant:
        ufr = etudiant.ufr.code.upper()
        infos = FlashInfo.objects.filter(ufr__in=['Tout',ufr],cible__in=['Tout','Etudiant'])
    elif enseignant:
        ufr = enseignant.ufr.code.upper()
        infos = FlashInfo.objects.filter(ufr__in=['Tout', ufr], cible__in=['Tout', 'Enseignant'])
    else:
        pass

    return infos


@register.filter(name='get_diffusion')
def get_diffusion(titre):
    sd = Diffusion.objects.filter(titre=titre).last()
    done = False
    if sd:
        done = sd.publier
    return done


@register.filter(name='get_edt_type_jour')
def get_edt_type_jour(field):
    if field in ['EXAMEN','CC TP','CC TD','CC']:
        return field
    else:
        return None


@register.filter(name='get_demande_by_type')
def get_demande_by_type(tp,key):
    if key=='obj':
        return DemandeActes.objects.filter(type_demande=tp,reception=False)
    elif key=='length':
        return len(DemandeActes.objects.filter(type_demande=tp,reception=False))


@register.filter(name='generer_password')
def generer_password(size):
    lower = "abcdefghijklmnopqrstuvwxyz"
    upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    numbers ="0123456789"
    symbols = "[]{}*;/._-"
    all =  lower + upper + numbers + symbols
    password = "".join(random.sample(all,size))

    return password


@register.filter(name='get_pub_cours_file')
def get_pub_cours_file(id,key):
    data = None
    if key =='p':
        data = PsPJoint.objects.filter(pub__id=id)
    elif key == 'c':
        data = PsPJoint.objects.filter(cours2__id=id)
    return data


@register.filter(name='get_pat_service')
def get_pat_service(personnel,key):
    srv = None
    if key =='last':
        srv1 = PersonnelService.objects.filter(personnel=personnel).order_by('-id').last()
        if srv1:
            srv = srv1.service
    elif key =='all':
        srv = [sv.service for sv in PersonnelService.objects.filter(personnel=personnel).order_by('-id')]
    elif key =='obj':
            srv = PersonnelService.objects.filter(personnel=personnel).order_by('-id')

    if srv:
        return srv
    else:
        return None


@register.filter(name='get_pat_responsabilite')
def get_pat_responsabilite(email):
    pat = Personnel.objects.filter(email=email).last()
    data = None
    if pat:
        data = pat.resposabilite
    return data