const axios = require("axios");
const shared = require("./shared.js");
const { Log } = require("./logs.js");

let userID;

async function TokenRenew() {
  setInterval(async () => {
    shared.eventEmitter.emit("tokenRenewalStart");
    // ottieni l'ID dell'utente associato al token
    userID = await getUserID();

    // ottieni l'ID del token corrente
    const tokenID = await getCurrentTokenID();

    // crea nuovo token
    const newToken = await getNewToken();
    shared.setToken(newToken);

    // cancella il token precedente
    await deleteToken(tokenID);
    shared.eventEmitter.emit("tokenRenewalEnd");
  }, day - hour);
}

async function getUserID() {
  let loopError;
  let errorCount = 0;
  do {
    try {
      const response = await axios.get(
        "https://api.netbird.io/api/users/current",
        {
          headers: {
            Accept: "application/json",
            Authorization: `Token ${shared.getToken()}`,
          },
        }
      );
      Log(`[${shared.now()}] UserID: ${response.data.id}`);
      return response.data.id;
    } catch (error) {
      loopError = true;
      Log(`[${shared.now()}] Errore nel reperire l'ID dell'utente corrente.`);
      Log(`[${shared.now()}] Codice HTTP ${error.response?.status}`);
        Log(`[${shared.now()}] Debug: ${error}`);
      for (const codice of shared.codiciNonAccettati) {
        if (error.response?.status === codice) {
          Log(
            `[${shared.now()}] Errore grave: il token inserito non esiste, non è valido o è scaduto.`
          );
          Log(
            `[${shared.now()}] Per favore riavviare il programma con un token valido.`
          );
          process.exit(3);
        }
      }
      Log(`[${shared.now()}] Nuovo tentativo n. ${errorCount++}`);
    }
  } while (loopError);
}

async function deleteToken(tokenID) {
  let loopError;
  let errorCount = 0;
  do {
    loopError = false;
    try {
      await axios.delete(
        `https://api.netbird.io/api/users/${userID}/tokens/${tokenID}`,
        {
          headers: {
            Authorization: `Token ${shared.getToken()}`,
          },
        }
      );
      Log(`[${shared.now()}] Token con ID ${tokenID} cancellato con successo`);
    } catch (error) {
      loopError = true;
      Log(
        `[${shared.now()}] Errore nella cancellazione del token con ID ${tokenID}.`
      );
      Log(`[${shared.now()}] Codice HTTP ${error.response?.status}`);
        Log(`[${shared.now()}] Debug: ${error}`);
      for (const codice of shared.codiciNonAccettati) {
        if (error.response?.status === codice) {
          Log(
            `[${shared.now()}] Errore grave: il token inserito non esiste, non è valido o è scaduto.`
          );
          Log(
            `[${shared.now()}] Per favore riavviare il programma con un token valido.`
          );
          process.exit(3);
        }
      }
      Log(`[${shared.now()}] Nuovo tentativo n. ${errorCount++}`);
    }
  } while (loopError);
}

async function getCurrentTokenID() {
  let loopError;
  let errorCount = 0;
  do {
    try {
      const response = await axios.get(
        `https://api.netbird.io/api/users/${userID}/tokens`,
        {
          headers: {
            Accept: "application/json",
            Authorization: `Token ${shared.getToken()}`,
          },
        }
      );

      const token = response.data.find((t) => t.name === "Uptime Kuma");
      if (!token) throw new Error("Token 'Uptime Kuma' non trovato");

      Log(`[${shared.now()}] CurrentTokenID: ${token.id}`);
      return token.id;
    } catch (error) {
      loopError = true;
      Log(`[${shared.now()}] Errore nel reperire il token corrente.`);
      Log(`[${shared.now()}] Codice HTTP ${error.response?.status}`);
        Log(`[${shared.now()}] Debug: ${error}`);
      for (const codice of shared.codiciNonAccettati) {
        if (error.response?.status === codice) {
          Log(
            `[${shared.now()}] Errore grave: il token inserito non esiste, non è valido o è scaduto.`
          );
          Log(
            `[${shared.now()}] Per favore riavviare il programma con un token valido.`
          );
          process.exit(3);
        }
      }
      Log(`[${shared.now()}] Nuovo tentativo n. ${errorCount++}`);
    }
  } while (loopError);
}

async function getNewToken() {
  let loopError;
  let errorCount = 0;
  do {
    try {
      const response = await axios.post(
        `https://api.netbird.io/api/users/${userID}/tokens`,
        {
          name: "Uptime Kuma",
          expires_in: 2,
        },
        {
          headers: {
            Accept: "application/json",
            Authorization: `Token ${shared.getToken()}`,
            "Content-Type": "application/json",
          },
        }
      );
      Log(`[${shared.now()}] Nuovo token creato: ${response.data.plain_token}`);
      return response.data.plain_token;
    } catch (error) {
      loopError = true;
      Log(`[${shared.now()}] Errore nella creazione di un nuovo token.`);
      Log(`[${shared.now()}] Codice HTTP ${error.response?.status}`);
        Log(`[${shared.now()}] Debug: ${error}`);
      for (const codice of shared.codiciNonAccettati) {
        if (error.response?.status === codice) {
          Log(
            `[${shared.now()}] Errore grave: il token inserito non esiste, non è valido o è scaduto.`
          );
          Log(
            `[${shared.now()}] Per favore riavviare il programma con un token valido.`
          );
          process.exit(3);
        }
      }
      Log(`[${shared.now()}] Nuovo tentativo n. ${errorCount++}`);
    }
  } while (loopError);
}

module.exports = {
  TokenRenew,
};
