#include <Arduino.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include "example_config.h"
#include "SmartCube/cubeSound.h"
#include "SmartCube/cubeButtons.h"
#include "SmartCube/cubeWifiManager.h"

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
cubeWifiManager cubeWifiManager(display);

unsigned long lastRefresh = 0;
const unsigned long refreshInterval = 60000; // 60 seconds
unsigned long lastDisplayUpdate = 0;
const unsigned long displayInterval = 100; // 100 ms

String lastEventId = "";
String problems[10];
String problemDescriptions;
int problemCount = 0;
int severityCounts[5] = {0};
bool newProblemsDetected = false;

void initSystems() {
  pinMode(PIN_BTN_L, INPUT);
  pinMode(PIN_BTN_M, INPUT);
  pinMode(PIN_BTN_R, INPUT);
  pinMode(PIN_BUZZER, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  Wire.begin();             // Initialize I2C
  Wire.setClock(400000L);    // Set I2C to Fast Mode (400 kHz)
  display.ssd1306_command(SSD1306_SETCONTRAST);
  display.ssd1306_command(200);  // Value between 0 and 255
  // Initialize the SSD1306 display
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adjust I2C address if needed
    for(;;); // Don't proceed, loop forever
  }

  // Rotate the display 180 degrees
  display.setRotation(2);

  // Clear the display buffer
  display.clearDisplay();
  display.setTextSize(1);      
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.display();
}

int totalProblems = 0; // Variable to store the total number of active problems

void fetchActiveProblems() {
  WiFiClient client;
  HTTPClient http;
  http.begin(client, zabbixServer);
  http.addHeader("Content-Type", "application/json");

  // JSON payload
  DynamicJsonDocument doc(1024);
  doc["jsonrpc"] = "2.0";
  doc["method"] = "problem.get";
  doc["id"] = 1;
  doc["auth"] = zabbixToken;
  JsonObject params = doc["params"].to<JsonObject>();
  params["output"] = "extend";
  params["recent"] = true;
  params["sortfield"] = "eventid";
  params["sortorder"] = "DESC";

  String requestBody;
  serializeJson(doc, requestBody);

  // POST request
  int httpResponseCode = http.POST(requestBody);

  if (httpResponseCode > 0) {
    String response = http.getString();

    // Parse response
    DynamicJsonDocument responseDoc(4096);
    deserializeJson(responseDoc, response);
    
    JsonArray result = responseDoc["result"].as<JsonArray>();
    int newProblemCount = 0;
    memset(severityCounts, 0, sizeof(severityCounts)); // Reset severities

    totalProblems = result.size(); // Set total problems count

    for (JsonObject problem : result) {
      String eventId = problem["eventid"].as<String>();
      int severity = problem["severity"].as<int>();
      String description = problem["name"].as<String>();

      // Check for new problems by comparing event IDs as integers
      if (eventId.toInt() > lastEventId.toInt()) {
        newProblemsDetected = true;
      }

      // Add new problem descriptions to the array
      if (newProblemCount < 10) {
        problems[newProblemCount] = description;
      }

      // Count severities
      if (severity >= 0 && severity < 5) {
        severityCounts[severity]++;
      }

      newProblemCount++;
      problemDescriptions += description;
    }

    problemCount = newProblemCount;

    // Update lastEventId after processing the most recent event
    if (problemCount > 0) {
      lastEventId = result[0]["eventid"].as<String>();
    }
  } else {
    beep(2000);
  }

  http.end();
}

int scrollPos = SCREEN_WIDTH;         // Global variable to keep track of the scroll position
unsigned long lastScrollTime = 0; // To control the scroll speed
const int scrollDelay = 150; // Delay in milliseconds between scroll updates

void displayProblems() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("Total Problems: ");
  display.print(totalProblems);  // Display total problems

  int stateWidth = strlen(problemDescriptions.c_str()) * 12;  // Approximate width of the status text in pixels
  // Scroll the text to the left
  if (!is_display_off) {
    if (millis() - lastScrollTime > scrollDelay) {
      // Update scroll position
      scrollPos -= 11;  // Move left by 1 pixel each time

      lastScrollTime = millis();

      // If the text has completely scrolled off, reset scroll position to start from the right
      if (scrollPos < -stateWidth) {
        scrollPos = SCREEN_WIDTH;
      }
    }
  }
  // Draw the file name with current scroll position
  display.setTextSize(2);
  display.setCursor(scrollPos, 54);
  display.print(problemDescriptions);
  display.setCursor(0, 44);
  display.setTextSize(1);
  
  display.display();
}

void setup() {
  initSystems();
  cubeWifiManager.start();
  fetchActiveProblems();
}

void loop() {
  unsigned long currentMillis = millis();
  cubeButtonHandler();

  if (!is_display_off && currentMillis - lastRefresh >= refreshInterval) {
    lastRefresh = currentMillis;
    fetchActiveProblems();
  }

  displayProblems();

  if (newProblemsDetected) {
    beep(1000);
    newProblemsDetected = false;
  }
}