#include "thingProperties.h"
#include <Arduino.h>
#include <HTTPClient.h>
#include <iostream>
#include <vector>
#include <cmath>

using namespace std;


const char* ssid = "Wokwi-GUEST";
const char* password = "";
HTTPClient client;
int LEDRED = 13;
int LEDGREEN = 12;
vector<double> theta = {0.1, 0.1};



void setup() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED){
    delay(500);
  }

  pinMode(LEDRED, OUTPUT);
  pinMode(LEDGREEN, OUTPUT);
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500);
  // Defined in thingProperties.h
  initProperties();
  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  /*
  The following function allows you to obtain more information
  related to the state of network and IoT Cloud connection and errors
  the higher number the more granular information you’ll get.
  The default is 0 (only errors).
  Maximum is 4
  */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  vector<double> x = {5.67, 3.35, 2.42, 5.93, 5.1, 4.88, 4.04, 1.06, 2.27, 1.47, 0.47, 4.42, 0.41, 5.22, 4.12, 4.73, 5.34, 0.53, 4.53, 2.67, 0.65, 4.77, 5.78, 1.75, 4.63, 1.01, 5.23, 2.09, 5.36, 1.13, 0.55, 1.66, 2.87, 5.89, 0.02, 5.04, 5.58, 5.96, 2.96, 1.87, 5.56, 5.29, 4.92, 5.24, 0.98, 5.14, 5.4, 2.28, 1.87, 0.79, 3.32, 3.72, 1.27, 5.33, 2.63, 0.38, 5.43, 0.26, 4.26, 5.89, 2.77, 4.17, 0.84, 0.73, 5.56, 4.87, 1.18, 1.27, 2.35, 5.55, 3.91, 4.91, 5.14, 0.38, 0.64, 5.28, 5.6, 4.83, 4.24, 4.04, 2.61, 0.16, 0.48, 5.06, 2.3, 4.85, 4.14, 0.44, 0.39, 3.95, 3.28, 4.29, 0.08, 5.74, 3.91, 4.72, 5.85, 1.16, 5.09, 5.21};
  vector<int> y = {1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1};

  theta = {-5.334103358722053, 1.5482712581534883};

  // Load the value of the learning rate (alpha)
  double alpha = 0.01;

  // Calculate the total number of samples from the data (n)
  int n = y.size();

  int num_iter = 10000;
/*
  for (int iter = 0; iter < num_iter; ++iter) {
      vector<double> delta;
      vector<double> delta1;
      
      
      for (int i = 0; i < n; ++i) {
          double pred = 1.0 / (1.0 + exp(-(theta[0] + theta[1] * x[i])));
          // Calculate delta for theta0 and for each sample
          // Calculate delta for theta1 and for each sample
          delta.push_back(pred - y[i]);
          delta1.push_back((pred - y[i]) * x[i]);
      }

      // Calculate summations and averages
      double dJt0 = 0.0;
      double dJt1 = 0.0;
      for (int i = 0; i < n; ++i) {
          dJt0 += delta[i];
          dJt1 += delta1[i];
      }
      dJt0 /= n;
      dJt1 /= n;

      // Update theta0 and theta1
      double theta0 = theta[0] - alpha * dJt0;
      double theta1 = theta[1] - alpha * dJt1;
      theta = {theta0, theta1};
  }
  */
}


void loop() {
  ArduinoCloud.update();
  random_value2 = random(0, 500);
  delay(500);
  Serial.print(".");
}


void onLedSwitch2Change() {
  if(led_switch2){
    digitalWrite(LEDRED, HIGH);
  }
  else{
    digitalWrite(LEDRED, LOW);
  }
}

void onHoursChange()  {
  double value = 1.0 / (1.0 + exp(-(theta[0] + theta[1] * hours)));
  int result = round(value);
  Serial.println(result);
  if (result == 1){
    digitalWrite(LEDRED, LOW);
    digitalWrite(LEDGREEN, HIGH);
  } else {
    digitalWrite(LEDRED, HIGH);
    digitalWrite(LEDGREEN, LOW);
  }
}