//https://circuits4you.com/2019/01/11/nodemcu-esp8266-arduino-json-parsing-example/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <LiquidCrystal_I2C.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

const char* SSID = "IFSC";
const char* PASSWORD = "campuschapeco";
LiquidCrystal_I2C lcd(0x27,16,2);
String BASE_URL = "http://www.projeto8.migueldebarba.com.br/testejson.php";

#define ledR  14
#define ledG  12
#define ledB  15
String payload;
String linhaum,linhadois;
String currentDate;

int diai, mesi, anoi;
int diaf, mesf, anof;

//Week Days
String weekDays[7]={"Domingo", "Segunda", "TerÃ§a", "Quarta", "Quinta", "Sexta", "SÃ¡bado"};
//Month names
String months[12]={"Janeiro", "Fevereiro", "MarÃ§o", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"};

void pegahora(){
timeClient.update();

time_t epochTime = timeClient.getEpochTime();
Serial.print("Epoch Time: ");
Serial.println(epochTime);

String formattedTime = timeClient.getFormattedTime();
Serial.print("Formatted Time: ");
Serial.println(formattedTime);  

int currentHour = timeClient.getHours();
Serial.print("Hour: ");
Serial.print(currentHour);  

int currentMinute = timeClient.getMinutes();
Serial.print(" - Minutes: ");
Serial.print(currentMinute); 
  
int currentSecond = timeClient.getSeconds();
Serial.print(" - Seconds: ");
Serial.println(currentSecond);  

String weekDay = weekDays[timeClient.getDay()];
Serial.print("Week Day: ");
Serial.println(weekDay);    

//Get a time structure
struct tm *ptm = gmtime ((time_t *)&epochTime); 

int monthDay = ptm->tm_mday;
Serial.print("Month day: ");
Serial.print(monthDay);

int currentMonth = ptm->tm_mon+1;
Serial.print(" - Month: ");
Serial.print(currentMonth);

String currentMonthName = months[currentMonth-1];
Serial.print(" - Month name: ");
Serial.println(currentMonthName);

int currentYear = ptm->tm_year+1900;
Serial.print("Year: ");
Serial.println(currentYear);

//Print complete date:
currentDate = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
Serial.print("Current date: ");
Serial.println(currentDate);  
}
void initSerial();
void initWiFi();
void httpRequest(String path);

// ############### OBJECTS ################# //

WiFiClient client;
HTTPClient http;
void setup() {

pinMode(ledR,OUTPUT);  pinMode(ledG,OUTPUT);  pinMode(ledB,OUTPUT);
initSerial();
initWiFi();
lcd.init();
lcd.setBacklight(HIGH);

// Initialize a NTPClient to get time
timeClient.begin();
// Set offset time in seconds to adjust for your timezone, for example:
// GMT +1 = 3600
// GMT +8 = 28800
// GMT -1 = -3600
// GMT 0 = 0
timeClient.setTimeOffset(-3600);

}

// ############# HTTP REQUEST ################ //

void httpRequest(String path)
{
String payload = makeRequest(path);
if (!payload) {
  return;
}
}

String makeRequest(String path)
{
http.begin(client, BASE_URL);
int httpCode = http.GET();                                  //Send the request
  if (httpCode > 0) { //Check the returning code
    payload = http.getString();   //Get the request response payload
  }

if (httpCode < 0) {
  Serial.println("request error - " + httpCode);
  return "";
}
if (httpCode != HTTP_CODE_OK) {
  return "";
}
String response =  http.getString();
http.end();
return response;
}

// implementacao dos prototypes

void initSerial() {
Serial.begin(115200);
}

void initWiFi() {
delay(10);
Serial.println("Conectando-se em: " + String(SSID));

WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
Serial.println();
Serial.print("Conectado na Rede " + String(SSID) + " | IP => ");
Serial.println(WiFi.localIP());
lcd.setCursor(0,0);
lcd.print(SSID);
lcd.setCursor(0,1);
lcd.print(WiFi.localIP());
delay(2000);

}

void showLetters(int printStart, int startLetter)
{
lcd.setCursor(printStart,0);
for (int currentLetter = startLetter; currentLetter < linhaum.length(); currentLetter++)
{
  lcd.print(linhaum[currentLetter]);
} 
lcd.print(" ");

lcd.setCursor(printStart,1);
for (int currentLetter = startLetter; currentLetter < linhadois.length(); currentLetter++)
{
  lcd.print(linhadois[currentLetter]);
} 

lcd.print(" ");
delay(250); 

}

void loop() {
Serial.println("[GET] /testejason.php");
Serial.println("");
httpRequest("GET");
Serial.println("payload:  " + payload);

// Cria documento JSON (buffer)
StaticJsonDocument<300> doc;
// Desserializa
DeserializationError error = deserializeJson(doc, payload);

if (error) {
  Serial.print(F("Erro ao desserializar: "));
  Serial.println(error.f_str());
  return;
}  

// Como Ã© um array, pegamos o primeiro elemento
JsonObject painel = doc[0];

// Acessa os campos
int idpainel = painel["idpainel"];
const char* mac = painel["mac_idmac"];
const char* nome = painel["nome"];
int ledr = painel["ledr"];
int ledg = painel["ledg"];
int ledb = painel["ledb"];

linhaum = painel["linhaum"].as<String>();  
linhadois = painel["linhadois"].as<String>();  
int t1=linhaum.length();
int t2=linhadois.length();
String datainicial=painel["datainicial"].as<String>();  
String datafinal=painel["datafinal"].as<String>();  

// Mostra no Display
for (int letter = 1; letter <= t1; letter++)  //scroll off to left
{    showLetters(0, letter);  }

// Mostra no LED RGB
analogWrite(ledR,ledr);
analogWrite(ledG,ledg);
analogWrite(ledB,ledb);

// Mostra no Serial
Serial.println("=== Dados do Painel ===");
Serial.print("ID: "); Serial.println(idpainel);
Serial.print("MAC: ");  Serial.println(mac);
Serial.print("Nome: ");  Serial.println(nome);
Serial.print("LED R: ");  Serial.println(ledr);
Serial.print("LED G: ");  Serial.println(ledg);
Serial.print("LED B: ");  Serial.println(ledb);  
Serial.print("Linha UM: ");  Serial.println(linhaum);  
Serial.print("Linha DOIS: ");  Serial.println(linhadois);  
Serial.print("Data inicial: ");  Serial.println(datainicial);  
sscanf(datainicial.c_str(), "%d/%d/%d", &anoi, &mesi, &diai);  
Serial.print("Dia: "); Serial.print(diai);Serial.print("MÃªs: "); Serial.print(mesi);Serial.print("Ano: "); Serial.println(anoi);
Serial.print("Data final: ");  Serial.println(datafinal);  
sscanf(datafinal.c_str(), "%d/%d/%d", &diaf, &mesf, &anof);  

pegahora();
Serial.print("Server date: ");
Serial.println(currentDate);  

delay(5000);
}