#include <a2_inferencing.h>
#include <Arduino.h>
#include <string.h>

const char* ssid     = "wifi_name";
const char* password = "wifi_password";
const char* host     = "host_ip";

#define SENSOR1_PIN A0
#define SENSOR2_PIN A1
#define SENSOR3_PIN A2
#define NUM_INPUTS EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE
float features[NUM_INPUTS];

void sendCommand(const String &cmd, unsigned long timeout);
void sendToServer(const String &label);

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

  Serial1.begin(115200);
  delay(2000);

  sendCommand("AT", 2000);
  sendCommand("AT+GMR", 2000);
  sendCommand("AT+CWMODE=1", 2000);

  String connectCmd = String("AT+CWJAP=\"") + ssid + "\",\"" + password + "\"";
  sendCommand(connectCmd, 10000);

  sendCommand("AT+CIPMUX=0", 2000);
}

void loop() {
  int s1 = analogRead(SENSOR1_PIN);
  int s2 = analogRead(SENSOR2_PIN);
  int s3 = analogRead(SENSOR3_PIN);

  if (NUM_INPUTS == 6) {
    features[0] = (float)s1;
    features[1] = (float)s2;
    features[2] = s3 / 10.0;
    features[3] = (float)s1;
    features[4] = (float)s2;
    features[5] = s3 / 10.0;
  }

  signal_t signal;
  signal.total_length = NUM_INPUTS;
  signal.get_data = [](size_t offset, size_t length, float *out_ptr) -> int {
    memcpy(out_ptr, features + offset, length * sizeof(float));
    return 0;
  };

  ei_impulse_result_t result = {0};
  EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
  if (res != EI_IMPULSE_OK) {
    delay(3000);
    return;
  }

  String label = result.classification[0].label;

  Serial.print("Classified: ");
  Serial.print(label);
  Serial.print(" | Features: ");
  Serial.print(features[0]);
  Serial.print(", ");
  Serial.print(features[1]);
  Serial.print(", ");
  Serial.println(features[2]);

  sendToServer(label);

  delay(3000);
}

void sendToServer(const String &label) {
  String message = "POST /send HTTP/1.1\r\n";
  message += "Host: " + String(host) + "\r\n";
  message += "Connection: close\r\n";
  message += "Content-Length: " + String(label.length()) + "\r\n\r\n";
  message += label;

  String cipstart = String("AT+CIPSTART=\"TCP\",\"") + host + "\",3000";
  sendCommand(cipstart, 3000);
  delay(1000);

  String cipsend = String("AT+CIPSEND=") + message.length();
  sendCommand(cipsend, 3000);
  delay(500);

  Serial.print("Sending POST request to ");
  Serial.println(host);

  Serial1.print(message);
  unsigned long startTime = millis();
  while (millis() - startTime < 3000) {
    if (Serial1.available()) {
      Serial1.readStringUntil('\n');
    }
  }
}

void sendCommand(const String &cmd, unsigned long timeout) {
  while (Serial1.available()) {
    Serial1.read();
  }
  Serial1.println(cmd);

  unsigned long start = millis();
  while (millis() - start < timeout) {
    if (Serial1.available()) {
      Serial1.readStringUntil('\n');
    }
  }
}
