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

// WiFi credentials
const char* ssid = "Wokwi-GUEST";         // Replace with your WiFi SSID
const char* password = "";                // Replace with your WiFi password

// URLs
const char* fetchUrl = "https://espenergymeter-cl1j558g.b4a.run/data"; // Fetch URL
const char* postUrl = "https://espenergymeter-cl1j558g.b4a.run/data";   // Post URL (use the same URL for posting)

// Variables
unsigned long previousMillis = 0;
const long interval = 5000; // 5 seconds
String userInput;
int voltage = 220;
int freq = 48;
bool load1State = true;
bool load2State = false;
bool load3State = true;
float current = 1.5;
float power = 330;
float energy = 0.1;
float pf = 0.87;
float amount = 15.0;

#define load1 4
#define load2 16
#define load3 17

String createJson() {
    String json = "{";
    json += "\"voltage\":" + String(voltage) + ",";
    json += "\"freq\":" + String(freq) + ",";
    json += "\"load1State\":" + String(load1State ? "true" : "false") + ",";
    json += "\"load2State\":" + String(load2State ? "true" : "false") + ",";
    json += "\"load3State\":" + String(load3State ? "true" : "false") + ",";
    json += "\"current\":" + String(current, 2) + ",";
    json += "\"power\":" + String(power, 2) + ",";
    json += "\"energy\":" + String(energy, 2) + ",";
    json += "\"pf\":" + String(pf, 2) + ",";
    json += "\"amount\":" + String(amount, 2);
    json += "}";
    return json;
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  pinMode(load1, OUTPUT);
  pinMode(load2, OUTPUT);
  pinMode(load3, OUTPUT);
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi!");
}

void loop() {
  // Fetch data every 5 seconds
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    postData();
    fetchData();
  }

}

void fetchData() {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(fetchUrl);  // Use HTTPS URL

    int httpResponseCode = http.GET();

    if (httpResponseCode > 0) {
      String response = http.getString();
      Serial.println("Fetched data: " + response);
      parseJson(response); // Call function to parse and set loads
    } else {
      Serial.println("Error in fetching data: " + String(httpResponseCode));
    }
    http.end();
  } else {
    Serial.println("WiFi not connected");
  }
}

void postData() {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(postUrl);  // Use HTTPS URL

    String jsonData = createJson();

    // Specify content type
    http.addHeader("Content-Type", "application/json");

    // Send POST request
    int httpResponseCode = http.POST(jsonData);

    if (httpResponseCode > 0) {
      String response = http.getString();
    } else {
      Serial.println("Error in posting data: " + String(httpResponseCode));
    }
    http.end();
  } else {
    Serial.println("WiFi not connected");
  }
}

// Function to parse JSON and set load states
void parseJson(String json) {
  StaticJsonDocument<256> doc;
  DeserializationError error = deserializeJson(doc, json);

  if (error) {
    Serial.print("JSON parse failed: ");
    Serial.println(error.c_str());
    return;
  }

  // Check and update load states
  if (doc.containsKey("load1State")) {
    load1State = doc["load1State"];
    digitalWrite(load1, load1State ? HIGH : LOW);
    Serial.print("Load 1 State: ");
    Serial.println(load1State ? "ON" : "OFF");
  }

  if (doc.containsKey("load2State")) {
    load2State = doc["load2State"];
    digitalWrite(load2, load2State ? HIGH : LOW);
    Serial.print("Load 2 State: ");
    Serial.println(load2State ? "ON" : "OFF");
  }

  if (doc.containsKey("load3State")) {
    load3State = doc["load3State"];
    digitalWrite(load3, load3State ? HIGH : LOW);
    Serial.print("Load 3 State: ");
    Serial.println(load3State ? "ON" : "OFF");
  }
}