#include <WiFi.h>
#include <HTTPClient.h>
#include <LiquidCrystal_I2C.h>
#include <ArduinoJson.h>

#include "button.h"

#define pin_btn 12

#define get_delay 30000 //период запроса погоды

LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 20, 4);
Button btn_button(pin_btn); 

const char* ssid = "Wokwi-GUEST";
const char* password = "";
const String endpoint = "http://api.openweathermap.org/data/2.5/weather?q=Moscow,ru,pt&units=metric&APPID=";
const String key = "cdecb72a7903eb3bb1964c39615f1764";

int current_time_0 = 0;

struct params_struct
{
  String param_name;
  int param_value;
};

const int params_num = 4; //просматривать 3 параметра

struct params_struct params[params_num] = {
    {"humidity", 0},
    {"temp", 1},
    {"feels", 2},
    {"invalid",3 }
};

params_struct* params_ptr = params;


void setup()  
{
  Serial.begin(115200);
  LCD.init();
  LCD.backlight();
  LCD.setCursor(0, 0);
  LCD.print("Scan networks...");
 
  LCD.clear();
  LCD.setCursor(0, 0);
  if (WiFi.scanNetworks() == 0) 
  {
    LCD.print("No networks found");
    while(1)
    {
      delay(100);
    }
  }
  

  LCD.clear();
  LCD.print("connecting to Wokwi-GUEST...");

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(200);
    draw_points();
  }
  LCD.clear();
  LCD.print("connected to "); 
  LCD.print(ssid);

  get_weather();
   
}

void draw_points()
{
  static int num = 0;
  LCD.setCursor(num, 1);
  LCD.print(".");
  num++;

  if (num > 5)
  {
    num = 0;
    LCD.setCursor(num, 1);
    LCD.print("     ");
  }
}


void loop() 
{  
  check_button();
  update_weather();
} 

void check_button()
{
if (btn_button.readButton())
  {
    params_ptr++;
    if ((*params_ptr).param_name == "invalid")
    {
      params_ptr = params;
    }    
    print_weather_param();
  }  
}

void print_weather_param()
  {
    LCD.clear();
    LCD.setCursor(0, 0);
    LCD.print("Weather in Moscow");

    LCD.setCursor(0, 1);
    LCD.print((*params_ptr).param_name);

    LCD.setCursor(0, 2);
    LCD.print((*params_ptr).param_value);
  }

void get_weather()
{ 
   // выполняем проверку подключения к беспроводной сети
  if ((WiFi.status() == WL_CONNECTED))
  {
    // создаем объект для работы с HTTP
    HTTPClient http;
    // подключаемся к веб-странице OpenWeatherMap с указанными параметрами
    http.begin(endpoint + key);
    int httpCode = http.GET(); // Делаем запрос
    // проверяем успешность запроса
    if (httpCode > 0)
    {
      // выводим ответ сервера
      String payload = http.getString();
      Serial.println(httpCode);
      //обработка полученных данных
      handleReceivedMessage(payload);
    }
    else {
      Serial.println("Ошибка HTTP-запроса");
    }
    http.end(); // освобождаем ресурсы микроконтроллера
  }
  print_weather_param();
  
}

void update_weather()
{
   
  if (millis() - current_time_0 < get_delay)
  {    
    return;
  }   

  get_weather(); 
  
  current_time_0 = millis();
}

 void handleReceivedMessage(String message)
  {
    StaticJsonDocument<1500> doc; //Memory pool. Размер с запасом
    //разбор полученного сообщения как форматированного текста JSON
    DeserializationError error = deserializeJson(doc, message);
    // Если разбор прошел успешно
    if (error)
    {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.c_str());
      return;
    }
    Serial.println();
    Serial.println("----- DATA FROM OPENWEATHER ----");
    const char* _name = doc["name"];
    Serial.print("City: ");
    Serial.println(_name);

    int _timezone = doc["timezone"];
    Serial.print("Timezone: ");
    Serial.println(_timezone);

    int _humidity = doc["main"]["humidity"];
    //humidity = _humidity;
    params[0].param_value = _humidity;
    Serial.print("Humidity: ");
    Serial.println(_humidity);

    int _temp = doc["main"]["temp"];
    //temp = _temp;
    params[1].param_value = _temp;
    Serial.print("temp: ");
    Serial.println(_temp);

    int _feels = doc["main"]["feels_like"];
    //feels = _feels;
    params[2].param_value = _feels;
    Serial.print("feels: ");
    Serial.println(_feels);

    Serial.println("------------------------------");
  }