#include "incl_01.h"
#include "inic_01.h"
#include "tarLED.h"

/***************Firebase********************************/
#include <WiFi.h>
#include <Firebase_ESP_Client.h>
#include <Wire.h>
#include "time.h"

// Timer variables (send new readings every three minutes)
unsigned long sendDataPrevMillis = 0;
unsigned long timerDelay = 180000;

// Provide the token generation process info.
#include "addons/TokenHelper.h"
// Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"

// credenciais de rede
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
// Inserir a API Key do projeto no Firebase
#define API_KEY "AIzaSyDq7b5j3eSDebXFUMePpvXhG7NlVa0I_Xs"
                

// Inserir o email autorizado e a correspondente senha
#define USER_EMAIL "[email protected]"
#define USER_PASSWORD "camila12"

// Inserir a URL definida para o RTDB 
#define DATABASE_URL "https://esp32proj1-default-rtdb.firebaseio.com/"

// Instanciar objetos da classe Firebase 
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;

// Variavel para  salvar o UID do USUÁRIO -  USER UID
String uid;

// Caminho principal do banco de dados 
//(to be updated in setup with the user UID)
String databasePath;

// NÓS FILHOS PARA O BANCO DE DADOS RTDB
String tempPath = "/temperature";
String humPath = "/humidity";
String timePath = "/timestamp";

// Parent Node (to be updated in every loop)
String parentPath;

int timestamp;
FirebaseJson json;

const char* ntpServer = "pool.ntp.org";

//protótipos de funções
void initWiFi();
unsigned long getTime();


void setup()
{
#include "setup_01.h"
/****************Firebase*******************************/
  initWiFi();
  configTime(0, 0, ntpServer);

  // Assign the api key (required)
  config.api_key = API_KEY;

  // Assign the user sign in credentials
  auth.user.email = USER_EMAIL;
  auth.user.password = USER_PASSWORD;

  // Assign the RTDB URL (required)
  config.database_url = DATABASE_URL;

  Firebase.reconnectWiFi(true);
  fbdo.setResponseSize(4096);

  // Assign the callback function for the long running token generation task */
  config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h

  // Assign the maximum retry of token generation
  config.max_token_generation_retry = 5;

  // Initialize the library with the Firebase authen and config
  Firebase.begin(&config, &auth);

  // Getting the user UID might take a few seconds
  Serial.println("Getting User UID");
  while ((auth.token.uid) == "") {
    Serial.print('.');
    delay(1000);
  }
  // Print user UID
  uid = auth.token.uid.c_str();
  Serial.print("User UID: ");
  Serial.println(uid);

  // Update database path
  databasePath = "/UsersData/" + uid + "/readings";
}

void loop() {
#include "loop_01.h"
/****************Firebase*******************************/
  // Send new readings to database
  if (Firebase.ready() && (millis() - sendDataPrevMillis > timerDelay || sendDataPrevMillis == 0)){
    sendDataPrevMillis = millis();

    //Get current timestamp
    timestamp = getTime();
    Serial.print ("time: ");
    Serial.println (timestamp);

    parentPath= databasePath + "/" + String(timestamp);
/*
    json.set(tempPath.c_str(), String(bme.readTemperature()));
    json.set(humPath.c_str(), String(bme.readHumidity()));
    json.set(presPath.c_str(), String(bme.readPressure()/100.0F));
    json.set(timePath, String(timestamp));
    Serial.printf("Set json... %s\n", Firebase.RTDB.setJSON(&fbdo, parentPath.c_str(), &json) ? "ok" : fbdo.errorReason().c_str());
*/
    float temperature = dht.getTemperature();
    float umidade = dht.getHumidity();
    
    json.set(tempPath.c_str(), String(temperature));
    json.set(tempPath.c_str(), String(umidade));
    json.set(timePath, String(timestamp));
    
    Serial.println(temperature); 
    Serial.println(umidade);
  
  }
}

// Initialize WiFi
void initWiFi() {
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }
  Serial.println(WiFi.localIP());
  Serial.println();
}

// Function that gets current epoch time
unsigned long getTime() {
  time_t now;
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    //Serial.println("Failed to obtain time");
    return(0);
  }
  time(&now);
  return now;
}