import hmac
import hashlib
from formatting_data2 import base64UrlDecode, base64UrlEncode
import json
from base64 import b64decode
import base64
import requests
import datetime
import math
import codecs


class boondManager:
    """cette class est l'equivalent de celle de Flo"""

    baseURL = "https://ui.boondmanager.com/api"
    appToken = "76656e646f725f385f31524b3744456f7565574a4c33427138374f566531487934584a6c6f47792b6b5f363530316562616532393030622e6f7474656f"
    cle = "199c5db56478f045b285"
    userToken = ""

    def safe_api_call(self, method, url, headers=None, data=None, files=None, timeout=10, retries=3):
        for attempt in range(retries):
            try:
                return requests.request(
                    method=method,
                    url=url,
                    headers=headers,
                    data=data,
                    files=files,
                    timeout=timeout,
                )
            except requests.exceptions.RequestException as e:
                print(f"[Tentative {attempt + 1}] Erreur API : {e}")
        return None

    def setBaseURL(self, url):
        self.baseURL = url
        return self.baseURL

    def setUserToken(self, token):
        self.userToken = token
        return self.userToken

    def signedRequestDecode(self, signedRequest):
        encodedSignature, payload = signedRequest.split(".", 1)

        if (
            codecs.decode(base64UrlDecode(encodedSignature))
            == hmac.new(
                codecs.encode(self.cle),
                codecs.encode(f"{payload}"),
                digestmod=hashlib.sha256,
            ).hexdigest()
        ):
            signedRequest = json.JSONDecoder().decode(
                base64.b64decode(codecs.encode(f"{payload}")).decode("utf-8")
            )
        else:
            signedRequest = False

        return signedRequest

    def jwEncode(self, payload):
        segments = []
        header = {"typ": "JWT", "alg": "HS256"}
        segments.append(base64UrlEncode(header))
        segments.append(base64UrlEncode(payload))

        L = [codecs.decode(i) for i in segments]
        signing_input = ".".join(map(str, L))
        signature = base64.b64encode(
            hmac.new(
                codecs.encode(self.cle),
                codecs.encode(signing_input),
                digestmod=hashlib.sha256,
            ).digest()
        ).decode()

        segments.append(
            base64.b64encode(
                hmac.new(
                    codecs.encode(self.cle),
                    codecs.encode(signing_input),
                    digestmod=hashlib.sha256,
                ).digest()
            )
            .replace(b"+", b"-")
            .replace(b"/", b"_")
        )

        L2 = [codecs.decode(i) for i in segments]
        return ".".join(map(str, L2))

    def callApi(self, api):
        payload = {
            "userToken": f"{self.userToken}",
            "appToken": f"{self.appToken}",
            "time": math.floor(datetime.datetime.now().timestamp()),
            "mode": "normal",
        }

        headers = {"X-Jwt-App-Boondmanager": self.jwEncode(payload)}
        data = {}
        url_path = f"{self.baseURL}/{api}"
        resp = self.safe_api_call(method="GET", url=url_path, headers=headers, data=data)

        status = resp.status_code
        if status == 200:
            return json.loads(resp.text)
        else:
            return False

    def modeliseData(self, url_path, headers, data, key_word, fromId):
        """cette fonction permet de remettre la données au format boond"""

        if key_word == "informations":
            data_to_post = json.loads(
                self.safe_api_call(
                    method="GET", url=url_path, headers=headers, data=""
                ).text
            )

            data_to_post["data"]["attributes"]["lastName"] = data["Nom"]
            data_to_post["data"]["attributes"]["firstName"] = data["Prénom"]
            data_to_post["data"]["attributes"]["typeOf"] = data["Statut souhaité"]
            data_to_post["data"]["attributes"]["availability"] = data["Disponibilité"]
            data_to_post["data"]["attributes"]["mobilityAreas"].extend(
                x
                for x in data["Mobilité"]
                if x not in data_to_post["data"]["attributes"]["mobilityAreas"]
            ) if data["Mobilité"] not in data_to_post["data"]["attributes"][
                "mobilityAreas"
            ] else data_to_post[
                "data"
            ][
                "attributes"
            ][
                "mobilityAreas"
            ]
            data_to_post["data"]["attributes"]["state"] = data["Décision"]
            data_to_post["data"]["attributes"]["informationComments"] += (
                "\n" + data["Commentaires suite à l EC"] + "\n"
            )

            notations = []
            for element in [
                i
                for i in data.keys()
                if i
                not in [
                    "Nom",
                    "Prénom",
                    "Disponibilité",
                    "Mobilité",
                    "Commentaires suite à l EC",
                    "Levier de motivation",
                    "Décision",
                    "Statut souhaité",
                ]
            ]:
                notations.append(
                    {
                        "criteria": int(element),
                        "evaluation": data[element],
                    }
                )
            data_to_post["data"]["attributes"]["evaluations"].append(
                {
                    "notations": notations,
                    "comments": data["Levier de motivation"],
                    "date": datetime.datetime.now().strftime("%Y-%m-%d"),
                }
            )
        elif key_word == "administrative":
            data_to_post = json.loads(
                self.safe_api_call(
                    method="GET", url=url_path, headers=headers, data=""
                ).text
            )
            data_to_post["data"]["attributes"]["nationality"] = data["Nationalité"]
            if "Salaire brut actuel" in data.keys():
                data_to_post["data"]["attributes"]["actualSalary"] = data[
                    "Salaire brut actuel"
                ]
            if "Detail salaire actuel" in data.keys():
                data_to_post["data"]["attributes"]["administrativeComments"] += (
                    "\nPackage salarial actuel : "
                    + data["Detail salaire actuel"]
                    + "\n"
                )
            if "salaire_souhaite_min" in data.keys():
                data_to_post["data"]["attributes"]["desiredSalary"]["min"] = data[
                    "salaire_souhaite_min"
                ]
            if "salaire_souhaite_max" in data.keys():
                data_to_post["data"]["attributes"]["desiredSalary"]["max"] = data[
                    "salaire_souhaite_max"
                ]
            data_to_post["data"]["attributes"]["administrativeComments"] += (
                "\nPermis de travail : " + data["Permis de travail"] + "\n"
            )
            if "tjm_actuel" in data.keys():
                data_to_post["data"]["attributes"]["actualAverageDailyCost"] = data[
                    "TJM_actuel"
                ]
            if "TJM_min" in data.keys() and "TJM_max" in data.keys():
                data_to_post["data"]["attributes"]["desiredAverageDailyCost"][
                    "min"
                ] = data["TJM_min"]
                data_to_post["data"]["attributes"]["desiredAverageDailyCost"][
                    "max"
                ] = data["TJM_max"]

        elif key_word in ["activity_area", "expertise_area"]:
            data_to_post = json.loads(
                self.safe_api_call(
                    method="GET", url=url_path, headers=headers, data=""
                ).text
            )
            # remove from  array the key diplomas and references
            del data_to_post["data"]["attributes"]["diplomas"]
            del data_to_post["data"]["attributes"]["references"]
            if key_word == "activity_area":
                # Convert data to list
                data_bis = data.split(",")
                # Convert simple quote in double quote
                data_to_post["data"]["attributes"]["activityAreas"] = data_bis
            elif key_word == "expertise_area":
                # Convert data to list
                data_bis = data.split(",")
                data_to_post["data"]["attributes"]["expertiseAreas"] = data_bis
        elif key_word == "technical_data":
            data_to_post = json.loads(
                self.safe_api_call(
                    method="GET", url=url_path, headers=headers, data=""
                ).text
            )

            # Remove data_to_post["data"]["attributes"]["references"] from dict
            del data_to_post["data"]["attributes"]["diplomas"]
            del data_to_post["data"]["attributes"]["references"]
            data_to_post["data"]["attributes"]["title"] = data["Titre"]
            data_to_post["data"]["attributes"]["skills"] += (
                "\nOutils : "
                + data["Outils"]
                + "\n"
                + "Entreprise precedentes : "
                + data["Entreprise precedentes"]
                + "\n"
                + "Metiers : "
                + data["Metiers"]
                + "\n"
            )
            data_to_post["data"]["attributes"]["languages"] = [
                {"language": data["Langue 1"], "level": data["Niveau Langue 1"]},
                {"language": data["Langue 2"], "level": data["Niveau Langue 2"]},
            ]
            data_to_post["data"]["attributes"]["experience"] = int(data["Experience"])
            if "Niveau d'étude" in data.keys():
                data_to_post["data"]["attributes"]["training"] = data["Niveau d'étude"]

        elif key_word == "actions":

            data_to_post = json.loads(
                self.safe_api_call(
                    method="GET", url=url_path, headers=headers, data=""
                ).text
            )
            data["Reference 1"] = (
                data["Reference contact 1"]
                + " - "
                + data["Reference Societe 1"]
                + " - "
                + data["Reference fonction 1"]
                + " - "
                + data["Reference telephone 1"]
                + " - "
                + data["Reference email 1"]
            )
            data["Reference 2"] = (
                data["Reference contact 2"]
                + " - "
                + data["Reference Societe 2"]
                + " - "
                + data["Reference fonction 2"]
                + " - "
                + data["Reference telephone 2"]
                + " - "
                + data["Reference email 2"]
            )
            del data["Reference contact 1"]
            del data["Reference Societe 1"]
            del data["Reference fonction 1"]
            del data["Reference telephone 1"]
            del data["Reference email 1"]
            del data["Reference contact 2"]
            del data["Reference Societe 2"]
            del data["Reference fonction 2"]
            del data["Reference telephone 2"]
            del data["Reference email 2"]
            del data_to_post["meta"]
            del data_to_post["data"]['id']
            data_to_post["data"]["attributes"]["text"] = "<table>"
            for key, value in data.items():
                # in value replace \n by <br> if exists
                if "\n" in value:
                    value = value.replace("\n", "<br>")
                data_to_post["data"]["attributes"][
                    "text"
                ] += f"<tr style='color:white;background-color:#09294c'><td>{key}</td><td style='color:black;background-color:white' colspan='3'>{value}</td></tr>"
            data_to_post["data"]["attributes"]["text"] += "</table>"
        elif key_word == "documents":
            data_to_post = {
                "parentType": "candidateResume",
                "parentId": fromId,
                "parsing": True,
            }
            return data_to_post
        return json.dumps(data_to_post)

    def putApi(self, api, data, key_word, fromId):
        payload = {
            "userToken": f"{self.userToken}",
            "appToken": f"{self.appToken}",
            "time": math.floor(datetime.datetime.now().timestamp()),
            "mode": "normal",
        }

        headers = {
            "X-Jwt-App-Boondmanager": self.jwEncode(payload),
            "Content-Type": "application/json",
        }
        url_path = f"{self.baseURL}/{api}"
        if key_word == "informations":
            data = self.modeliseData(url_path, headers, data, key_word, fromId)

            respget = self.safe_api_call(
                method="GET", url=url_path, headers=headers, data=""
            )

            resp = self.safe_api_call(
                method="PUT", url=url_path, headers=headers, data=data
            )

            status = resp.status_code
            # print(status)
            # print(resp.text)
            if status == 200:
                return json.loads(resp.text)
            else:
                return False

        else:
            data = self.modeliseData(url_path, headers, data, key_word, fromId)
            resp = self.safe_api_call(
                method="PUT", url=url_path, headers=headers, data=data
            )
            print(data)
            status = resp.status_code
            print(status)
            print(resp.text)
            if status == 200:
                return json.loads(resp.text)
            else:
                return False

    def postApi(self, api, data, key_word, fromId):
        payload = {
            "userToken": f"{self.userToken}",
            "appToken": f"{self.appToken}",
            "time": math.floor(datetime.datetime.now().timestamp()),
            "mode": "normal",
        }

        headers = {
            "X-Jwt-App-Boondmanager": self.jwEncode(payload),
            "Content-Type": "application/json",
        }
        url_path = f"{self.baseURL}/{api}"
        if key_word == "documents":
            headers = {
                "X-Jwt-App-Boondmanager": self.jwEncode(payload),
            }
            data_m = {
                "parentType": "candidateResume",
                "parentId": fromId,
                "parsing": True,
            }
            data = [
                (
                    "file",
                    (
                        data,
                        open('/var/www/dossier_candidat/app/word/' + str(data, 'utf-8'), "rb"),
                        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                    ),
                )
            ]
            resp = self.safe_api_call(
                method="POST", url=url_path, headers=headers, data=data_m, files=data
            )
            status = resp.status_code
            print(resp.text)
            if status == 200:
                return json.loads(resp.text)
            else:
                return False

        else:
            data = self.modeliseData(url_path, headers, data, key_word, fromId)

            resp = self.safe_api_call(
                method="POST", url=url_path, headers=headers, data=data
            )

            status = resp.status_code

            if status == 200:
                return json.loads(resp.text)
            else:
                return False
