import csv

from django.shortcuts import redirect, render
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from .models import *
from .custom_admin_form import *
from django.contrib import messages
from session_tracking.utils import *
from Scolarite.models import AgentScolarite


#TODO : CUSTOM ADMIN HOME
@login_required(login_url='BasicData:login')
def custom_admin(request):
    context ={}
    return render(request,'other_admin/home.html',context)

#+++++++++++++ CRUD ETUDIANT ++++++++++++++++++
@login_required(login_url='BasicData:login')
def etudiant_list(request):
    # On recupere tout les Etudiants
    try:
        etudiants = Etudiant.objects.filter(actif=True).order_by('nom')
    except Etudiant.DoesNotExist:
        etudiants = None

    # ON RECUPERE LES UFR
    ufrs = Ufr.objects.all().order_by('code')

    form = CsvUploadForm()
    if request.method == 'POST':
        form = CsvUploadForm(request.POST or None, request.FILES or None)
        etobj = None
        if form.is_valid():
            form.save()
            cd = form.cleaned_data
            ufr = cd.get('ufr')

            form = CsvUploadForm()
            obj = Csv.objects.get(activated=False)
            obj.activated = True
            obj.save()
            with open(obj.file_name.path, 'r') as f:
                reader = csv.reader(f)
                for i, row in enumerate(reader):
                    if i == 0:
                        pass
                    else:
                        row = "".join(row)
                        # on remplace les espaces avec par des " _ "
                        row = row.replace(" ", "_")
                        # on repmlace " ; " par des espaces
                        row = row.replace(";", " ")
                        row = row.split()
                        # ON RECUPERE LES DONNEES

                        check = Etudiant.objects.filter(nce=row[0].upper()).last()

                        if check:
                            messages.error(request,"L'étudiant ["+str(check.nce)+"] existe déja")
                        else:

                            etobj = Etudiant.objects.create(
                                nce=row[0].upper(),
                                nom=row[1].upper(),
                                prenoms=row[2].replace("_"," ").upper(),
                                ufr = Ufr.objects.get(id=ufr),
                                actif=False
                            )
                            etobj.email =str(row[1][0])+str(row[2][0])+str(etobj.id)+ '@user.cm'
                            etobj.save()

            if etobj:
                messages.success(request,'Importation réussie -- [étudiants-'+str(Ufr.objects.get(id=ufr).code)+']')
                return redirect('/etudiant_list/')
            else:
                messages.error(request, "Echec d'importation ")
                return redirect('/etudiant_list/')

    context = {
        'page_obj': etudiants,
        'form':form,
        'ufrs':ufrs,
    }
    return render(request,'other_admin/etudiant/etudiant_list.html',context)


@login_required(login_url='BasicData:login')
def etudiant_add(request):
    # UFRs
    ufrs = Ufr.objects.all()
    niveaux = Niveau.objects.all()
    annee = Annee.objects.last()
    show_form = 'show'

    form = EtudiantAddForm()
    if request.method == 'POST':
        form = EtudiantAddForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            nce = cd.get('nce').upper()
            nom = cd.get('nom').upper()
            prenoms = cd.get('prenoms').upper()
            sexe = cd.get('sexe')
            datenaiss = cd.get('datenaiss')
            lieunaiss = cd.get('lieunaiss')
            phone = cd.get('phone')
            email = cd.get('email')
            password = cd.get('password').replace(" ","")
            password2 = cd.get('password2').replace(" ","")
            ufr = cd.get('ufr')
            niveau = cd.get('niveau')

            # ON RECUPERE LA LISTE DES EMAILS ET TELEPHONES POUR COMPARAISON
            nces = Etudiant.objects.filter(nce=nce)
            mails = Etudiant.objects.filter(email=email)
            phones = Etudiant.objects.filter(phone=phone)

            # GESTION DES CONTRAINTES
            if password != password2:
                messages.error(request, 'Les mots de passe sont différents')
            elif len(password) < 8:
                messages.error(request, 'Le mot de passe doit être au moins 8 caractères')
            elif '/' in password:
                messages.error(request, "Le mot de passe ne doit pas contenir de '/' ")
            elif mails:
                messages.error(request, 'Ce Email existe déja')
            elif nces:
                messages.error(request, 'Ce NCE existe déja')
            elif phones:
                messages.error(request, 'Ce Numéro de téléphone existe déja')
            else:
                etudiant = Etudiant.objects.create(
                    nce = nce,
                    nom = nom,
                    prenoms = prenoms,
                    sexe = sexe,
                    datenaiss = datenaiss,
                    lieunaiss = lieunaiss,
                    phone = phone,
                    email = email
                )
                etudiant.set_password(password)
                etudiant.save()
                NiveauEtudiant.objects.create(
                    etudiant=etudiant,
                    niveau = Niveau.objects.get(id=niveau),
                    annee=annee
                )
                # action tracker
                track_insert(request.user.email, [etudiant], "nouvel etudiant")


                # ON RECUPERE LES UE DE L'UFR
                for ue in ParcoursSemestreUe.objects.filter(ue__ufr__id=ufr):
                    # On verifie si parcoursSemestreUe existe deja pour cet etudiant
                    try:
                        EtudiantUes = EtudiantUe.objects.filter(etudiant=etudiant, parcoursSemestreUe=ue)
                    except EtudiantUe.DoesNotExist:
                        EtudiantUes = None

                    # Si oui on passe sans enregistrer
                    if EtudiantUes:
                        pass
                    else:
                        # Sinon on crée le nouvel objet
                        EtudiantUe.objects.create(etudiant=etudiant, parcoursSemestreUe=ue)

                show_form ='hide'
                messages.success(request, "Etudiant '"+ str(etudiant.nce)+"' enregisté avec succès")
        else:
            form = EtudiantAddForm()

    context ={
        'form':form,
        'ufrs':ufrs,
        'show_form':show_form,
        'niveaux':niveaux,
    }
    return render(request, 'other_admin/etudiant/etudiant_add.html', context)

@login_required(login_url='BasicData:login')
def etudiant_edit(request,id):
    ufrs = Ufr.objects.all()
    form = EtudiantAddForm()

    # ON RECUPERE LES DONNEES DE L'ETUDIANT
    try:
        etudiant = Etudiant.objects.get(id=id)
    except Etudiant.DoesNotExist:
        etudiant = None

    form = EtudiantEditForm(instance=etudiant)
    if request.method == 'POST':
        form = EtudiantEditForm(request.POST, instance=etudiant)
        if form.is_valid():
            form.save()
            # action tracker
            track_insert(request.user.email, [etudiant], "modifier infos etudiant")
            messages.success(request, 'Modifié avec succès!')
            return redirect('/etudiant_list/')
        else:
            messages.error(request, 'vérifiez les champs svp!')
            messages.error(request, form.errors)

    context = {
        'form': form,
        'ufrs': ufrs,
        'etudiant':etudiant
    }
    return render(request, 'other_admin/etudiant/etudiant_edit.html', context)


#+++++++++++++ CRUD ENSEIGANT ++++++++++++++++++
@login_required(login_url='BasicData:login')
def enseignant_list(request):
    # On recupere tout les Etudiants
    try:
        enseignants = Enseignant.objects.filter(is_ue=False).order_by('-id')
    except Enseignant.DoesNotExist:
        enseignants = None
    # Nombre total d'étudiant
    total = len(enseignants)

    # pagination
    page = request.GET.get('page', 1)
    paginator = Paginator(enseignants, 1000)
    try:
        Pobject = paginator.page(page)
    except PageNotAnInteger:
        Pobject = paginator.page(1)
    except EmptyPage:
        Pobject = paginator.page(paginator.num_pages)

    context = {
        'page_obj': Pobject,
        'total':total
    }
    return render(request,'other_admin/enseignant/enseignant_list.html',context)


@login_required(login_url='BasicData:login')
def enseignant_add(request):
    # UFRs
    annee = Annee.objects.last()
    ufrs = Ufr.objects.all()
    grades = Grade.objects.all()
    show_form = 'show'

    form = EnseignantAddForm()
    if request.method == 'POST':
        form = EnseignantAddForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            nom = cd.get('nom').upper()
            specialite = cd.get('specialite')
            statut = cd.get('statut')
            prenoms = cd.get('prenoms').upper()
            sexe = cd.get('sexe')
            datenaiss = cd.get('datenaiss')
            lieunaiss = cd.get('lieunaiss')
            phone = cd.get('phone')
            email = cd.get('email')
            password = cd.get('password').replace(" ","")
            password2 = cd.get('password2').replace(" ","")
            ufr = cd.get('ufr')
            grade = cd.get('grade')
            is_ufr_dg = cd.get('is_ufr_dg')

            # ON RECUPERE LA LISTE DES EMAILS ET TELEPHONES POUR COMPARAISON
            mails = Enseignant.objects.filter(email=email)
            phones = Enseignant.objects.filter(phone=phone)

            # GESTION DES CONTRAINTES
            if password != password2:
                messages.error(request, 'Les mots de passe sont différents')
            elif len(password) < 8:
                messages.error(request, 'Le mot de passe doit être au moins 8 caractères')
            elif '/' in password:
                messages.error(request, "Le mot de passe ne doit pas contenir de '/' ")
            elif mails:
                messages.error(request, 'Ce Email existe déja')
            elif phones:
                messages.error(request, 'Ce Numéro de téléphone existe déja')
            else:
                # Simple Enseignant
                if is_ufr_dg =='0':
                    enseignant = Enseignant.objects.create(
                        nom=nom,
                        prenoms=prenoms,
                        specialite=specialite,
                        statut=statut,
                        sexe=sexe,
                        datenaiss=datenaiss,
                        lieunaiss=lieunaiss,
                        phone=phone,
                        email=email,
                        grade=Grade.objects.get(id=grade),
                        ufr=Ufr.objects.get(id=ufr),
                        profile=True
                    )
                    enseignant.set_password(password)
                    enseignant.save()

                    # action tracker
                    track_insert(request.user.email, [enseignant],"nouvel enseignant")


                    show_form = 'hide'
                    messages.success(request, "Enseignant '" + str(enseignant.nom) + " " + str(
                        enseignant.prenoms) + "' enregisté avec succès")
                # Dr UFR
                elif is_ufr_dg =='1':
                    enseignant = Enseignant.objects.create(
                        nom=nom,
                        prenoms=prenoms,
                        specialite=specialite,
                        statut=statut,
                        sexe=sexe,
                        datenaiss=datenaiss,
                        lieunaiss=lieunaiss,
                        phone=phone,
                        email=email,
                        grade=Grade.objects.get(id=grade),
                        ufr=Ufr.objects.get(id=ufr),
                        is_ufr_dg=True
                    )
                    enseignant.set_password(password)
                    # ON CREE LES UFR DE L'ENSEIGNANT
                    enseignant.save()

                    # action tracker
                    track_insert(request.user.email, [enseignant],"nouvel enseignant")

                    show_form = 'hide'
                    messages.success(request, "Enseignant '" + str(enseignant.nom) + " " + str(
                        enseignant.prenoms) + "' enregisté avec succès")
                # Vice Président
                elif is_ufr_dg == '3':
                    enseignant = Enseignant.objects.create(
                        nom=nom,
                        prenoms=prenoms,
                        specialite=specialite,
                        statut=statut,
                        sexe=sexe,
                        datenaiss=datenaiss,
                        lieunaiss=lieunaiss,
                        phone=phone,
                        email=email,
                        grade=Grade.objects.get(id=grade),
                        ufr=Ufr.objects.get(id=ufr),
                        is_vp=True
                    )
                    enseignant.set_password(password)
                    # ON CREE LES UFR DE L'ENSEIGNANT
                    enseignant.save()
                    # action tracker
                    track_insert(request.user.email, [enseignant],"nouvel enseignant")

                    show_form = 'hide'
                    messages.success(request, "Enseignant '" + str(enseignant.nom) + " " + str(
                        enseignant.prenoms) + "' enregisté avec succès")
                # Président
                elif is_ufr_dg == '4':
                    enseignant = Enseignant.objects.create(
                        nom=nom,
                        prenoms=prenoms,
                        specialite=specialite,
                        statut=statut,
                        sexe=sexe,
                        datenaiss=datenaiss,
                        lieunaiss=lieunaiss,
                        phone=phone,
                        email=email,
                        grade=Grade.objects.get(id=grade),
                        ufr=Ufr.objects.get(id=ufr),
                        is_pr=True
                    )
                    enseignant.set_password(password)
                    # ON CREE LES UFR DE L'ENSEIGNANT
                    enseignant.save()

                    # action tracker
                    track_insert(request.user.email, [enseignant],"nouvel enseignant")

                    show_form = 'hide'
                    messages.success(request, "Enseignant '" + str(enseignant.nom) + " " + str(
                        enseignant.prenoms) + "' enregisté avec succès")
                else:
                    enseignant = Enseignant.objects.create(
                        nom = nom,
                        prenoms = prenoms,
                        specialite=specialite,
                        statut=statut,
                        sexe = sexe,
                        datenaiss = datenaiss,
                        lieunaiss = lieunaiss,
                        phone = phone,
                        email = email,
                        grade = Grade.objects.get(id=grade),
                        ufr=Ufr.objects.get(id=ufr),
                        is_respo = True
                    )
                    enseignant.set_password(password)
                    enseignant.save()

                    # action tracker
                    track_insert(request.user.email, [enseignant],"nouvel enseignant")

                    show_form ='hide'
                    messages.success(request, "Enseignant '"+ str(enseignant.nom)+" "+str(enseignant.prenoms)+"' enregistré avec succès")
        else:
            form = EnseignantAddForm()
            messages.error(request,form.errors)

    context ={
        'form':form,
        'ufrs':ufrs,
        'grade':grades,
        'show_form':show_form
    }
    return render(request, 'other_admin/enseignant/enseignant_add.html',context)


@login_required(login_url='BasicData:login')
def enseignant_edit(request,id):
    ufrs = Ufr.objects.all()
    grade = Grade.objects.all()
    form = EnseignantEditForm()

    # ON RECUPERE LES DONNEES DE L'ETUDIANT
    try:
        enseignant = Enseignant.objects.get(id=id)
    except Enseignant.DoesNotExist:
        enseignant = None

    form = EnseignantEditForm(instance=enseignant)
    if request.method == 'POST':
        form = EnseignantEditForm(request.POST, instance=enseignant)
        if form.is_valid():
            form.save()
            cd = form.cleaned_data
            #ufr = cd.get('ufr')

            # action tracker
            track_insert(request.user.email, [enseignant], "modifier infos enseignant")

            messages.success(request, 'Modifié avec succès !')
            return redirect('/enseignant_list/')
        else:
            messages.error(request, 'vérifiez les champs svp!')
            #messages.error(request, form.errors)

    context = {
        'form': form,
        'ufrs': ufrs,
        'enseignant':enseignant,
        'grade':grade
    }
    return render(request, 'other_admin/enseignant/enseignant_edit.html', context)



@login_required(login_url='BasicData:login')
def enseignant_ufr_list(request,id):
    enseignant = Enseignant.objects.get(id=id)
    # ON RECUPERE LES UFRS DE L'ENSEIGNANT
    ufrs = EnseignantUfr.objects.filter(annee=Annee.objects.last(),enseignant=enseignant).order_by('-id')

    addForm = AddEnseignantUFRForm()
    if request.method == 'POST':
        if 'addbtn' in request.POST:
            addForm = AddEnseignantUFRForm(request.POST)
            if addForm.is_valid():
                cd = addForm.cleaned_data
                ufr = cd.get('ufr')

                # ON VERIFIE SI L'ENSEIGNANT FAIT PARTIR DE CETTE UFR
                getUfr = EnseignantUfr.objects.filter(
                    annee=Annee.objects.last(),
                    enseignant=enseignant,
                    ufr=ufr
                )
                if getUfr:
                    messages.error(request, "L'enseignant fait déja partir de cette UFR")
                    return redirect('/enseignant_ufr_list/' + str(id) + '/')
                else:
                    EnseignantUfr.objects.create(
                        annee = Annee.objects.last(),
                        enseignant = enseignant,
                        ufr = ufr
                    )
                    # action tracker
                    track_edit(request.user.email, [enseignant,ufr],"affecter l'enseignant à l'ufr")
                    messages.success(request,"Enseignant affilié à l'UFR")
                    addForm = AddEnseignantUFRForm()
                    return redirect('/enseignant_ufr_list/'+str(id)+'/')
            else:
                messages.error(request,'Vérifiez les Champs svp')
                return redirect('/enseignant_ufr_list/' + str(id) + '/')

    # DELETE OBJECT
    delForm = DelEnseignantUFRForm()
    if request.method == 'POST':
        if 'delbtn' in request.POST:
            delForm = DelEnseignantUFRForm(request.POST)
            if delForm.is_valid():
                cd= delForm.cleaned_data
                ufrid = cd.get('ufrid')

                getUFR = EnseignantUfr.objects.get(id=ufrid)
                # action tracker
                track_delete(request.user.email,[enseignant,getUFR.ufr],"retirer l'enseignant de ufr")
                getUFR.delete()
                messages.success(request, "UFR retirée")
                delForm = DelEnseignantUFRForm()
                return redirect('/enseignant_ufr_list/' + str(id) + '/')
            else:
                messages.error(request,'Vérifiez les Champs svp')
                return redirect('/enseignant_ufr_list/' + str(id) + '/')


    context={
        'ufrs':ufrs,
        'enseignant':enseignant,
        'addForm':addForm,
    }
    return render(request, 'other_admin/enseignant/enseignant_ufr_list.html', context)


@login_required(login_url='BasicData:login')
def ag_scolartie_list(request):
    agents = AgentScolarite.objects.all().order_by('nom')

    context ={
        'agents':agents,
    }
    return render(request,'other_admin/scolarite/ag_scolarite_list.html',context)


@login_required(login_url='BasicData:login')
def ag_scolartie_add(request):
    show_form = 'show'

    form = AgAddForm()
    if request.method == 'POST':
        form = AgAddForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            nom = cd.get('nom').upper()
            prenoms = cd.get('prenoms').upper()
            sexe = cd.get('sexe')
            datenaiss = cd.get('datenaiss')
            lieunaiss = cd.get('lieunaiss')
            phone = cd.get('phone')
            email = cd.get('email')
            password = cd.get('password').replace(" ", "")
            password2 = cd.get('password2').replace(" ", "")

            # ON RECUPERE LA LISTE DES EMAILS ET TELEPHONES POUR COMPARAISON
            mails = User.objects.filter(email=email)
            phones = User.objects.filter(phone=phone)

            # GESTION DES CONTRAINTES
            if password != password2:
                messages.error(request, 'Les mots de passe sont différents')
            elif len(password) < 8:
                messages.error(request, 'Le mot de passe doit être au moins 8 caractères')
            elif '/' in password:
                messages.error(request, "Le mot de passe ne doit pas contenir de '/' ")
            elif mails:
                messages.error(request, 'Ce Email existe déja')
            elif phones:
                messages.error(request, 'Ce Numéro de téléphone existe déja')
            else:
                ags = AgentScolarite.objects.create(
                    nom=nom,
                    prenoms = prenoms,
                    sexe = sexe,
                    datenaiss = datenaiss,
                    lieunaiss =lieunaiss,
                    phone = phone,
                    email = email
                )
                ags.set_password(password)
                ags.save()
                # action tracker
                track_insert(request.user.email, [ags], "Nouvel agent de scolarité")

                messages.success(request,'Enregistrement réussi')
                show_form = 'hide'
        else:
            messages.error(request,'Vérifiez les champs svp!')

    context={
        'form':form,
        'show_form':show_form,
    }
    return render(request, 'other_admin/scolarite/ag_scolarite_add.html', context)


@login_required(login_url='BasicData:login')
def ag_scolarite_edit(request,id):

    # ON RECUPERE L'AGENT
    agent = AgentScolarite.objects.get(id=id)

    form = AgEditform(instance=agent)
    if request.method == 'POST':
        form = AgEditform(request.POST, instance=agent)
        if form.is_valid():
            form.save()
            # action tracker
            track_insert(request.user.email, [agent], "Modifier agent de scolarité")
            messages.success(request, 'Enregistrement réussi')
            return redirect('/agent_scolartie_list/')
        else:
            messages.error(request, 'Vérifiez les champs svp!')


    context = {
        'form': form,
        'agent': agent,
    }
    return render(request, 'other_admin/scolarite/ag_scolarite_edit.html', context)



@login_required(login_url='BasicData:login')
def personnel_list(request):
    user = User.objects.get(email=request.user.email)
    # On recupere tout les Etudiants
    personnel = Personnel.objects.all().order_by('nom')
    # Nombre total d'étudiant
    total = len(personnel)

    # ADD PERSONNEL
    form = PersonnelAddForm()
    if request.method =='POST':
        if 'addPersonBtn' in request.POST:
            form = PersonnelAddForm(request.POST)
            if form.is_valid():
                cd = form.cleaned_data
                nom = cd.get('nom').upper()
                prenoms = cd.get('prenoms').upper()
                sexe = cd.get('sexe')
                datenaiss = cd.get('datenaiss')
                lieunaiss = cd.get('lieunaiss')
                pdfonc = cd.get('prise_de_fonction')
                role = cd.get('resposabilite')
                phone = cd.get('phone')
                regime = cd.get('regime')
                email = cd.get('email')
                password = cd.get('password').replace(" ", "")
                password2 = cd.get('password2').replace(" ", "")

                # ON RECUPERE LA LISTE DES EMAILS ET TELEPHONES POUR COMPARAISON
                mails = User.objects.filter(email=email)
                phones = User.objects.filter(phone=phone)

                # GESTION DES CONTRAINTES
                if password != password2:
                    messages.error(request, 'Les mots de passe sont différents')
                elif len(password) < 8:
                    messages.error(request, 'Le mot de passe doit être au moins 8 caractères')
                elif '/' in password:
                    messages.error(request, "Le mot de passe ne doit pas contenir de '/' ")
                elif mails:
                    messages.error(request, 'Ce Email existe déja')
                elif phones:
                    messages.error(request, 'Ce Numéro de téléphone existe déja')
                else:
                    persos = Personnel.objects.create(
                        nom=nom,
                        prenoms=prenoms,
                        sexe=sexe,
                        datenaiss=datenaiss,
                        lieunaiss=lieunaiss,
                        phone=phone,
                        email=email,
                        prise_de_fonction=pdfonc,
                        resposabilite =role,
                        regime =regime
                    )
                    persos.set_password(password)
                    persos.save()
                    # action tracker
                    track_insert(request.user.email, [persos], "Nouveau personnel A.T.")

                    messages.success(request, 'Enregistrement réussi')
                    return redirect('BasicData:personnel_list')
            else:
                messages.error(request, 'Vérifiez les champs svp!')
                messages.error(request, form.errors)

    # ADD SERVICE
    form2 = AddServiceForm()
    if request.method == 'POST':
        if 'addServiceBtn' in request.POST:
            form2 = AddServiceForm(request.POST)
            if form2.is_valid():
                cd = form2.cleaned_data
                ps = Personnel.objects.get(id=cd.get('personnel').id)
                psObj = form2.save(commit=False)
                psObj.personnel = ps
                form2.save()
                # action tracker
                track_insert(request.user.email, [ps], "Affecter un PAT dans un service")

                messages.success(request, 'Enregistrement réussi')
                return redirect('BasicData:personnel_list')
            else:
                messages.error(request, 'Vérifiez les champs svp!')
                messages.error(request, form.errors)

    context = {
        'personnel': personnel,
        'total':total,
        'form':form,
        'form2':form2,
        'user':user,
    }
    return render(request,'other_admin/personnel/personnel_list.html',context)


@login_required(login_url='BasicData:login')
def personnel_edit(request,id):
    # ON RECUPERE L'AGENT
    personnel = Personnel.objects.get(id=id)

    form = PersonnelEditForm(instance=personnel)
    if request.method == 'POST':
        form = PersonnelEditForm(request.POST, instance=personnel)
        if form.is_valid():
            form.save()
            # action tracker
            track_insert(request.user.email, [personnel], "Modifier personnel A.T.")
            messages.success(request, 'Enregistrement réussi')
            return redirect('BasicData:personnel_list')
        else:
            messages.error(request, 'Vérifiez les champs svp!')
            messages.error(request, form.errors)


    context = {
        'form': form,
        'personnel': personnel,
    }
    return render(request, 'other_admin/personnel/personnel_edit.html', context)