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

// WiFi credentials
const char *ssid = "Wokwi-GUEST";
const char *password = "";

// Server and user configuration
const char *serverUrl = "https://1be56469-efc1-4d75-8a1a-ad3133b3084a-00-2tx68ed5s69to.sisko.replit.dev/predict/";
const char *nodeName = "atharva";

// Sensor pins
const int dht22SensorPin = 4;
const int rainSensorPin = 12;      // Digital pin: HIGH means rain, LOW means no rain
const int flowSensorPin = 14;      // Analog pin: Water flow sensor
const int floatSensorPin = 27;     // Digital pin: HIGH means water max, LOW means water low
const int ultrasonicPin = 27;      // Ultrasonic sensor pin for river water level (in mm)

// Global variables for parameters
int monsoonIntensity;
int topographyDrainage;
int riverManagement;
int climateChange;
int siltation;
int drainageSystems;
int coastalVulnerability;
int watersheds;
int deterioratingInfrastructure;
int wetlandLoss;

// Function prototypes
void calculateParameters();
void makeGetRequest();

void setup() {
  Serial.begin(115200);

  // Connect to WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");
}

void calculateParameters() {
  // Read sensor values
  int rainStatus = digitalRead(rainSensorPin); // HIGH = rain, LOW = no rain
  int flowRate = analogRead(flowSensorPin);    // Flow sensor analog reading
  int floatStatus = digitalRead(floatSensorPin); // HIGH = max water, LOW = low water
  int riverLevel = analogRead(ultrasonicPin);  // River level in mm

  // Calculate parameters based on sensor readings and formulas
  monsoonIntensity = rainStatus ? 7 : 3; // If raining, high monsoon intensity
  topographyDrainage = map(riverLevel, 0, 4095, 1, 10); // River level mapped to scale
  riverManagement = map(flowRate, 0, 4095, 1, 10);      // Flow rate mapped to scale
  climateChange = (floatStatus == HIGH) ? 8 : 4;        // High water level indicates climate change impact
  siltation = map(riverLevel, 0, 4095, 2, 7);           // River level mapped to siltation scale
  drainageSystems = 10 - map(flowRate, 0, 4095, 1, 8);  // Low flow indicates better drainage
  coastalVulnerability = map(rainStatus, 0, 1, 5, 10);  // High rain increases coastal vulnerability
  watersheds = map(riverLevel, 0, 4095, 3, 9);          // River level mapped to watershed health
  deterioratingInfrastructure = (floatStatus == HIGH) ? 9 : 4; // Max water indicates deterioration
  wetlandLoss = rainStatus ? 6 : 2;                     // Rain increases wetland loss likelihood
}

void makeGetRequest() {
  HTTPClient http;

  // Calculate parameters before making the GET request
  calculateParameters();

  // Construct the URL with calculated parameters
  String url = String(serverUrl) +
               "?NodeName=" + nodeName +
               "&MonsoonIntensity=" + monsoonIntensity +
               "&TopographyDrainage=" + topographyDrainage +
               "&RiverManagement=" + riverManagement +
               "&ClimateChange=" + climateChange +
               "&Siltation=" + siltation +
               "&DrainageSystems=" + drainageSystems +
               "&CoastalVulnerability=" + coastalVulnerability +
               "&Watersheds=" + watersheds +
               "&DeterioratingInfrastructure=" + deterioratingInfrastructure +
               "&WetlandLoss=" + wetlandLoss;

  Serial.println("Sending GET request to: " + url);

  http.begin(url);

  int httpCode = http.GET();
  if (httpCode > 0) {
    Serial.printf("HTTP response code: %d\n", httpCode);
    String payload = http.getString();
    Serial.println("Server response: " + payload);
  } else {
    Serial.printf("HTTP request failed, error: %s\n", http.errorToString(httpCode).c_str());
  }

  http.end();
}

void loop() {
  // Make the API call every 20 seconds
  makeGetRequest();
  delay(20000);
}