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

#include "Button.h"

#define BUTTON 2

struct Weather
{
  int temp;        //doc["main"]["temp"]
  int feels_like;  //doc["main"]["feels_like"]
  int humidity;    //doc["main"]["humidity"]
};

Weather curWeather;
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 fieldNum = 0;
volatile bool newAsk = true;
volatile bool newPush = false;
LiquidCrystal_I2C display(0x27, 16, 2);

void showNextField()
{
  ++fieldNum;
  Serial.println("showNextField");
  display.clear();
  display.setCursor(0,0);
  switch(fieldNum)
  {
    case 0:
      display.print("Temperature:");
      display.setCursor(0,1);
      display.print(curWeather.temp);            
    break;
    case 1:
      display.print("Feels like:");
      display.setCursor(0,1);
      display.print(curWeather.feels_like);
    break;
    case 2:
      display.print("Humidity:");
      display.setCursor(0,1);
      display.print(curWeather.humidity);
      fieldNum = -1;
    break;
  }
};

void handleReceivedMessage(String message)
{
  StaticJsonDocument<1500> doc; 
  DeserializationError error = deserializeJson(doc, message);
  if (error)
  {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }
  curWeather.temp = doc["main"]["temp"];
  curWeather.feels_like = doc["main"]["feels_like"];
  curWeather.humidity = doc["main"]["humidity"];
}

void askWeather()
{
  Serial.println("askWeather");
  if((WiFi.status() == WL_CONNECTED))
  {  
    HTTPClient http;  
    http.begin(endpoint + key);
    int httpCode = http.GET();  
    if (httpCode > 0)
    {
      String payload = http.getString();      
      handleReceivedMessage(payload);      
    }
    else 
    {
      Serial.println("Ошибка HTTP-запроса");
    }
    http.end();
    --fieldNum;
    showNextField();
  }
}

Button button(BUTTON, showNextField);
hw_timer_t *timer;

void setup() 
{
  Serial.begin(115200);
  delay(1000);
  
  timer = timerBegin(0, APB_CLK_FREQ/1000000, true);
  timerAttachInterrupt(timer, [&newAsk](){newAsk = true;}, true);
  timerAlarmWrite(timer, 30000000, true);
  timerAlarmEnable(timer);

  attachInterrupt(digitalPinToInterrupt(BUTTON), [&newPush](){newPush = true;}, CHANGE);

  Wire.begin(21,22);
  display.begin(16,2);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(1000);
    Serial.println("Соединяемся с Wi-Fi..");
  }
  Serial.println("Соединение с Wi-Fi установлено"); 
}

void loop() 
{
  if(newAsk)
  {
    askWeather();
    newAsk = false;
  }
  if(newPush)
  {
    button.process();
    newPush = false;
  }
  //delay(10);
}
esp:0
esp:2
esp:4
esp:5
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:21
esp:22
esp:23
esp:25
esp:26
esp:27
esp:32
esp:33
esp:34
esp:35
esp:3V3
esp:EN
esp:VP
esp:VN
esp:GND.1
esp:D2
esp:D3
esp:CMD
esp:5V
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:D1
esp:D0
esp:CLK
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r