"""
Ce fichier defini les comment les activités sont gérées
Par principe, une activié peut etre faite par plusieurs entités (client, partner, user, etc).
Donc à l'image des contact, on va gerer la notion de :
- related_collection
- relected_recid
- type (email, call, meeting, cmd, devis, autre),
- Description
- detail
- deadline
- status : encours, fait, annulé.
"""


import pymongo
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime
import prj_common as mycommon
import secrets
import inspect
import sys, os
import csv
import pandas as pd
from pymongo import ReturnDocument
import GlobalVariable as MYSY_GV
from math import isnan
import GlobalVariable as MYSY_GV
import ela_index_bdd_classes as eibdd
import email_mgt as email
import ast


"""
Ajout d'une activité
"""
def Add_activite(diction):

    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', "description", "detail", "deadline", "type",
                      "status", 'related_collection', 'related_collection_owner_email',
                      'employee_assigned_to_id']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'existe pas")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', 'related_collection', 'related_collection_owner_email',]

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification de l'identité et autorisation de l'entité qui
        appelle cette API
        """
        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        partner_recid = mycommon.get_parnter_recid_from_token(token)
        if (partner_recid is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - partner_recid est KO. Les données de connexion sont incorrectes ")
            return False, " Vous n'etes pas autorisé à utiliser cette API "

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_recid(partner_recid)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données du partenaire")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données du partenaire. "



        """
                Recuperation des données fournies en entrée
                """
        data = {}
        data['partner_recid'] = my_partner['recid']

        employee_assigned_to_id = ""
        if ("employee_assigned_to_id" in diction.keys()):
            if diction['employee_assigned_to_id']:
                employee_assigned_to_id = diction['employee_assigned_to_id']

                ## Verifier que l'employé assigné existe et est valide
                is_employee_assigned_to_count = MYSY_GV.dbname['ressource_humaine'].count_documents(
                    {'_id': ObjectId(str(employee_assigned_to_id)), 'valide': '1', 'locked': '0',
                     'partner_recid': str(my_partner['recid'])})

                if( is_employee_assigned_to_count != 1 ):
                    mycommon.myprint(
                        str(inspect.stack()[0][3]) + " - L'employé assigné est invalide")
                    return False, str(inspect.stack()[0][3]) + "  - L'employé assigné est invalide "


        data['employee_assigned_to_id'] = employee_assigned_to_id



        description = ""
        if ("description" in diction.keys()):
            if diction['description']:
                description = diction['description']


        if(len(str(description)) > 255 ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - Le champ 'description' doit faire moins de 255 caractères ")

            return False, "  - Le champ 'description' doit faire moins de 255 caractères "

        data['description'] = diction['description']

        detail = ""
        if ("detail" in diction.keys()):
            if diction['detail']:
                detail = diction['detail']

        if (len(str(detail)) > 500):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - Le champ 'detail' doit faire moins de 500 caractères ")

            return False, "  - Le champ 'detail' doit faire moins de 500 caractères "
        data['detail'] = diction['detail']


        deadline = ""
        if ("deadline" in diction.keys()):
            if diction['deadline']:
                deadline = diction['deadline']
                data['deadline'] = diction['deadline']

                local_status = mycommon.CheckisDate(deadline)
                if (local_status is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][3]) + " - La date deadline n'est pas au format jj/mm/aaaa ")

                    return False, " - La date deadline n'est pas au format jj/mm/aaaa "



        status = ""
        if ("status" in diction.keys()):
            status = diction['status']

            if (status not in MYSY_GV.ACTIVITE_STATUS):
                mycommon.myprint(
                    "- Le statut " + str(status) + " n'est pas autorisé ")
                return False, "- Le statut " + str(status) + " n'est pas autorisé "

        data['status'] = diction['status']

        type = ""
        if ("type" in diction.keys()):
            if diction['type']:
                type = diction['type']

                if( type not in MYSY_GV.ACTIVITE_TYPE):
                    mycommon.myprint(
                        "- Le type d' activite   "+str(type)+" n'est pas autorisé")
                    return False, "- Le type d' activite   "+str(type)+" n'est pas autorisé"

        data['type'] = diction['type']
        

        related_collection = ""
        if ("related_collection" in diction.keys()):
            if diction['related_collection']:
                related_collection = diction['related_collection']
                data['related_collection'] = diction['related_collection']
                if (related_collection not in MYSY_GV.ACTIVITE_COLLECTION):
                    mycommon.myprint(
                        "- La collection   " + str(related_collection) + " n'accepte pas d' activite ")
                    return False,  "- La collection   " + str(related_collection) + " n'accepte pas d' activite "

        if ("related_collection_owner_email" in diction.keys()):
            related_collection_owner_email = str(diction['related_collection_owner_email'])
            """
            Recuperation du recid associé au related_collection_owner_email dans la collection :  related_collection
            """
            # print(" #### on cherche le recid du mail "+ str(related_collection_owner_email)+" dans la collection "+str(diction['related_collection'])+" ." )
            local_tmp_val = MYSY_GV.dbname[str(diction['related_collection'])].find_one(
                {'email': related_collection_owner_email})
            if (local_tmp_val is None or "recid" not in local_tmp_val.keys()):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - impossible de récupérer les données de " + str(
                        related_collection_owner_email) + " dans la collection " + str(diction['related_collection']))
                return False, str(inspect.stack()[0][3]) + " - impossible de récupérer les données de " + str(
                    related_collection_owner_email) + " dans la collection " + str(
                    diction['related_collection']) + " . "

            data['related_collection_recid'] = str(local_tmp_val['recid'])

        data['valide'] = '1'
        data['locked'] = '0'
        data['date_update'] = str(datetime.now())

        # Creation du RecId
        data['recid'] = mycommon.create_user_recid()


        inserted_id = ""
        inserted_id = MYSY_GV.dbname['activite'].insert_one(data).inserted_id
        if (not inserted_id):
            mycommon.myprint(
                " Impossible de créer l'activité ")
            return False, " Impossible de créer l'activité  "


        return True, " L'activité a été correctement créée"

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible d'ajouter l'activité "


"""
Mise à jour d'une activité en se basant sur : 
'token', ==> partner_recid
'related_collection', 
'related_collection_recid' 

"""
def Update_activite(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
               Verification des input acceptés
               """
        field_list = ['token', "description", "detail", "deadline", "type",
				"status",'activite_recid' , 'employee_assigned_to_id']


        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'existe pas")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', 'activite_recid' ]

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification de l'identité et autorisation de l'entité qui
        appelle cette API
        """
        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        partner_recid = mycommon.get_parnter_recid_from_token(token)
        if (partner_recid is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - partner_recid est KO. Les données de connexion sont incorrectes ")
            return False, " Vous n'etes pas autorisé à utiliser cette API "

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_recid(partner_recid)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données du partenaire")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données du partenaire. "

        """
                Verification s'il n'existe pas un cient du partenaire qui perte le meme
                nom, ou la meme adresse email
                 """

        qry_update = {'valide': '1', 'locked':'0', 'partner_recid': str(my_partner['recid']),
         'recid':str(diction['activite_recid']),}



        print(" ### qry_update = ", qry_update)

        tmp_count = MYSY_GV.dbname['activite'].count_documents(qry_update)
        if (tmp_count <= 0):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " - Cette activité n'existe pas: related_collection_recid = "+str(diction['related_collection_recid']))

            return False, " -  Cette activité n'existe pas, mise à jour impossible "



        """
        Recuperation des données fournies en entrée
        """

        data_update = {}
        """
                        Recuperation des données fournies en entrée
                        """

        description = ""
        if ("description" in diction.keys()):
            description = diction['description']
            data_update['description'] = diction['description']

        if (len(str(description)) > 255):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - Le champ 'description' doit faire moins de 255 caractères ")

            return False, "  - Le champ 'description' doit faire moins de 255 caractères "

        detail = ""
        if ("detail" in diction.keys()):
            detail = diction['detail']
            data_update['detail'] = diction['detail']

        if (len(str(detail)) > 500):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - Le champ 'detail' doit faire moins de 500 caractères ")

            return False, "  - Le champ 'detail' doit faire moins de 500 caractères "

        deadline = ""
        if ("deadline" in diction.keys()):
            if diction['deadline']:
                deadline = diction['deadline']
                data_update['deadline'] = diction['deadline']

                local_status = mycommon.CheckisDate(deadline)
                if (local_status is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][3]) + " - La date deadline n'est pas au format jj/mm/aaaa ")

                    return False, " - La date deadline n'est pas au format jj/mm/aaaa "

        employee_assigned_to_id = ""
        if ("employee_assigned_to_id" in diction.keys()):
            if diction['employee_assigned_to_id']:
                employee_assigned_to_id = diction['employee_assigned_to_id']

                ## Verifier que l'employé assigné existe et est valide
                is_employee_assigned_to_count = MYSY_GV.dbname['ressource_humaine'].count_documents(
                    {'_id': ObjectId(str(employee_assigned_to_id)), 'valide': '1', 'locked': '0',
                     'partner_recid': str(my_partner['recid'])})

                if (is_employee_assigned_to_count != 1):
                    mycommon.myprint(
                        str(inspect.stack()[0][3]) + " - L'employé assigné est invalide")
                    return False, str(inspect.stack()[0][3]) + "  - L'employé assigné est invalide "

            data_update['employee_assigned_to_id'] = diction['employee_assigned_to_id']

        status = ""
        if ("status" in diction.keys()):
            status = diction['status']
            data_update['status'] = diction['status']
            if (status not in MYSY_GV.ACTIVITE_STATUS):
                mycommon.myprint(
                    "- Le statut " + str(status) + " n'est pas autorisé ")
                return False, "- Le statut " + str(status) + " n'est pas autorisé "

        type = ""
        if ("type" in diction.keys()):
            type = diction['type']
            data_update['type'] = diction['type']
            if (type not in MYSY_GV.ACTIVITE_TYPE):
                mycommon.myprint(
                    "- Le type d' activite   " + str(type) + " n'est pas autorisé")
                return False, "- Le type d' activite   " + str(type) + " n'est pas autorisé"


        data_update['valide'] = '1'
        data_update['locked'] = '0'
        data_update['date_update'] = str(datetime.now())

        """
                Clés de mise à jour 
        """
        data_cle = {}
        data_cle['partner_recid'] = str(my_partner['recid'])
        data_cle['recid'] = str(diction['activite_recid'])
        data_cle['valide'] = "1"
        data_cle['locked'] = "0"

        inserted_id = ""
        result = MYSY_GV.dbname['activite'].find_one_and_update(
            data_cle,
            {"$set": data_update},
            upsert=False,
            return_document=ReturnDocument.AFTER
        )
        if ("_id" not in result.keys()):
            mycommon.myprint(
                " Impossible de mettre à jour l'activité : related_collection_recid = " + str(diction['related_collection_recid']))
            return False, " Impossible de mettre à jour l'activité  "

        return True, " L'activité a été correctement mise à jour"

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de mettre à jour l'activité "


"""
Recuperation de la liste des activité d'une entité en se basant sur 
- related_collection
- token (partner_recid)
- related_collection_recid (s'il est fourni)

/!\ : apres avoir récupérer les info, on va ajouter 1 : 'retard'
 calcul du retard = deadline - date_day:
 >= pas en retard
 < 0 : en de tard de X jours 
- 
"""
def Get_List_Entity_Activite(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'related_collection', 'related_collection_owner_email']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'existe pas")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', 'related_collection']
        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification de l'identité et autorisation de l'entité qui
        appelle cette API
        """
        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_token(token)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur ")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données de l'utilisateur. "

        """
                Clés de mise à jour 
                """
        data_cle = {}
        data_cle['partner_recid'] = str(my_partner['recid'])
        data_cle['related_collection'] = str(diction['related_collection'])

        if ("related_collection_owner_email" in diction.keys()):
            related_collection_owner_email = str(diction['related_collection_owner_email'])
            """
            Recuperation du recid associé au related_collection_owner_email dans la collection :  related_collection
            """

            local_tmp_val = MYSY_GV.dbname[str(diction['related_collection'])].find_one(
                {'email': related_collection_owner_email})

            if (local_tmp_val is None or "recid" not in local_tmp_val.keys()):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - impossible de récupérer les données de " + str(
                        related_collection_owner_email) + " dans la collection " + str(diction['related_collection']))
                return False, str(inspect.stack()[0][3]) + " - impossible de récupérer les données de " + str(
                    related_collection_owner_email) + " dans la collection " + str(
                    diction['related_collection']) + " . "

            data_cle['related_collection_recid'] = str(local_tmp_val['recid'])

        data_cle['locked'] = "0"

        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['activite'].find(data_cle):
            user = retval
            user['id'] = str(val_tmp)

            retard = "0"
            if( "deadline" in retval.keys() ):
                local_status = mycommon.CheckisDate(retval['deadline'])
                if( local_status is not False ):
                    mytoday = datetime.today().strftime("%d/%m/%Y")
                    retard = (datetime.strptime(str(retval['deadline']), '%d/%m/%Y') - datetime.strptime(str(mytoday), '%d/%m/%Y')).days

            user['retard'] = str(retard)

            val_tmp = val_tmp + 1
            RetObject.append(mycommon.JSONEncoder().encode(user))

        return True, RetObject


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de récupérer la liste des activités "


"""
Recuperation d'une activité donnée en se basant sur on token, activite_recid
"""
def Get_Given_Activite(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'activite_recid']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'existe pas")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire =  ['token', 'activite_recid']
        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification de l'identité et autorisation de l'entité qui
        appelle cette API
        """
        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_token(token)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur ")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données de l'utilisateur. "

        """
                Clés de mise à jour 
                """
        data_cle = {}
        data_cle['partner_recid'] = str(my_partner['recid'])
        data_cle['recid'] = str(diction['activite_recid'])

        data_cle['valide'] = "1"
        data_cle['locked'] = "0"

        RetObject = []
        val_tmp = 1

        #print(" ### data_cle = ", data_cle)
        for retval in MYSY_GV.dbname['activite'].find(data_cle):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1

            # Si le champ 'employee_assigned_to_id' alors on va chercher le nom et prenom de l'employe au quel est assigné la tache (employe)
            if ('employee_assigned_to_id' in retval.keys()):
                Employee_data = MYSY_GV.dbname['ressource_humaine'].find_one(
                    {'_id': ObjectId(str(retval['employee_assigned_to_id'])), 'valide': '1', 'locked': '0',
                     'partner_recid': str(my_partner['recid'])})

                employee_assigned_to_nom_prenom = ""
                if (Employee_data and 'nom' in Employee_data.keys()):
                    employee_assigned_to_nom_prenom = str(Employee_data['nom'])

                if (Employee_data and 'prenom' in Employee_data.keys()):
                    employee_assigned_to_nom_prenom = str(employee_assigned_to_nom_prenom) + " " + str(
                        Employee_data['prenom'])

                user['employee_assigned_to_nom_prenom'] = str(employee_assigned_to_nom_prenom)



            RetObject.append(mycommon.JSONEncoder().encode(user))

        #print(" ### RetObject = ", RetObject)
        return True, RetObject


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de récupérer l'activité "

