#include <WiFi.h>
#include <SPI.h>  //https://www.arduino.cc/en/reference/SPI
//#include <secrets.h>
#include <WiFiClientSecure.h>
#include <MQTTClient.h>
#include <ArduinoJson.h>
#include <pgmspace.h>
#include <iostream>
#include <sstream>
#define SECRET
#define THINGNAME ""
#include "esp_wpa2.h"

#define AWS_IOT_PUBLISH_TOPIC ""
#define AWS_IOT_SUBSCRIBE_TOPIC ""

WiFiClientSecure net = WiFiClientSecure();
MQTTClient client = MQTTClient(256);

#define EAP_ANONYMOUS_IDENTITY "" //[email protected], or you can use also [email protected]
#define EAP_IDENTITY "" //[email protected], at some organizations should work nickname only without realm, but it is not recommended
#define EAP_PASSWORD "" //password for eduroam account

const char* ssid = ""; // eduroam SSID
const char AWS_IOT_ENDPOINT[] = "";

// Amazon Root CA 1
static const char AWS_CERT_CA[] PROGMEM = ;

// Device Certificate
static const char AWS_CERT_CRT[] PROGMEM = ;

// Device Private Key
static const char AWS_CERT_PRIVATE[] PROGMEM = ;


#define SS_PIN 5
#define RST_PIN 0
#define solenoidValve 25


#define SENSOR 27
long currentMillis = 0;
long previousMillis = 0;
int interval = 1000;
//boolean ledState = LOW;
float calibrationFactor = 17;
volatile byte pulseCount;
byte pulse1Sec = 0;
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
int water = 0;
int amount = 0;


void IRAM_ATTR pulseCounter() {
  pulseCount++;
}


// The MQTT topics that this device should publish/subscribe


void connectToWifi() {
  Serial.println("Connecting to WiFi...");

  WiFi.disconnect(true);
  delay(1000);

  WiFi.begin("Wokwi-GUEST", "", 6);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("...");
  }

  Serial.println("WiFi connected");
}

void connectToMqtt() {
  Serial.println("Connecting to MQTT...");

  while (!client.connect(THINGNAME, AWS_IOT_ENDPOINT, 9011 )) {
    Serial.println(".");
    delay(1000);
  }

  Serial.println("MQTT connected");
}




void processCompleted() {
  StaticJsonDocument<200> doc;
  doc["is_completed"] = true;
  char jsonBuffer[512];
  serializeJson(doc, jsonBuffer);  // print to client

  client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
  Serial.println("message sent");
}



void messageHandler(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);
  delay(1000);

  amount = atoi(payload.c_str());
}



void setup() {

  Serial.begin(115200);
  Serial.println(F("Initialize System"));
  connectToWifi();
  connectToMqtt();
  pinMode(SENSOR, INPUT_PULLUP);
  pulseCount = 0;
  flowRate = 0.0;
  flowMilliLitres = 0;
  totalMilliLitres = 0;
  previousMillis = 0;
  attachInterrupt(digitalPinToInterrupt(SENSOR), pulseCounter, FALLING);
  SPI.begin();
  pinMode(solenoidValve, OUTPUT);
}

void loop() {
  client.loop();
  delay(1000);


  while (amount > 0) {
    currentMillis = millis();
    digitalWrite(solenoidValve, HIGH);
    if (currentMillis - previousMillis > interval) {
      pulse1Sec = pulseCount;
      pulseCount = 0;


      flowRate = ((1000.0 / (millis() - previousMillis)) * pulse1Sec) / calibrationFactor;
      previousMillis = millis();
      flowMilliLitres = (flowRate / 60) * 1000;
      totalMilliLitres += flowMilliLitres;
      // Print the flow rate for this second in litres / minute
      Serial.print("Flow rate: ");
      Serial.print(int(flowRate));  // Print the integer part of the variable
      Serial.print("L/min");
      Serial.print("\t");  // Print tab space
      // Print the cumulative total of litres flowed since starting
      Serial.print("Output Liquid Quantity: ");
      Serial.print(totalMilliLitres);
      Serial.print("mL / ");
      Serial.print(totalMilliLitres / 1000);
      Serial.println("L");
      if (totalMilliLitres >= amount) {

        Serial.println("ANANIN AMI");
        processCompleted();
        Serial.println("Process Completed message sent");
        digitalWrite(solenoidValve, LOW);
        Serial.print("Valve closed");
        delay(500);
        amount = 0;
        totalMilliLitres = 0;
        delay(500);

      }

    }

  }

}