#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h> 
#include <ArduinoJson.h>
#include <Wire.h>
#include <U8g2lib.h>

// OLED display dimensions
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Create an instance of the U8g2 library for SSD1306 (adjust the constructor based on your display)
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);  // Hardware I2C constructor

const char* ssid = "WIFI_SSID";
const char* password = "PASSWORD";
const char* gemini_api_key = "GEMINI_API_KEY";
const char* weather_api_key = "OWM_API_KEY";
const char* gemini_server = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=";
const char* weather_server = "http://api.openweathermap.org/data/2.5/weather";

unsigned long previousMillis = 0;
const long interval = 3600000; // 1 hour in milliseconds

void display_text(String s1, String s2, String s3)
{
// Clear the screen buffer
  u8g2.clearBuffer();

  // Set the font to small monospace
  u8g2.setFont(u8g2_font_helvB08_tr);  // Small monospace font

  // First line: ~5 words (at the top)
  u8g2.setCursor(0, 9); 
  u8g2.print(String(s1));

  // Fourth line: ~5 words
  u8g2.setCursor(0, 40); 
  u8g2.print(String(s2));

  // Fifth line: ~5 words
  u8g2.setCursor(0, 60); 
  u8g2.print(String(s3));

  // Send the buffer to the display
  u8g2.sendBuffer();
}

String getWeatherData() {
  HTTPClient http;
  WiFiClient client;
  
  String url = String(weather_server) + 
               "?q=Bangalore,IN" + 
               "&appid=" + weather_api_key + 
               "&units=metric";  // Use metric units
               
  http.begin(client, url);
  int httpResponseCode = http.GET();
  
  if (httpResponseCode > 0) {
    String payload = http.getString();
    
    // Parse weather JSON
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    
    // Extract relevant weather information
    float temp = doc["main"]["feels_like"];
    int humidity = doc["main"]["humidity"];
    String description = doc["weather"][0]["description"];
    
    String weatherSummary = "Temperature: " + 
                           String(temp) + "°C, Humidity: " + 
                           String(humidity) + "%, Condition: " + 
                           description;
    
    http.end();
    return weatherSummary;
  }
  
  http.end();
  return "Error getting weather data";
}

void fetchAndProcessData() {
  if (WiFi.status() == WL_CONNECTED) {
    // First get weather data
    String weatherData = getWeatherData();
    Serial.println("Weather Data: " + weatherData);
    
    // Now send to Gemini for summarization
   // Create secure client
    WiFiClientSecure client;
    client.setInsecure(); // Skip certificate verification
    
    // Create HTTP client
    HTTPClient https;

    String url = String(gemini_server) + gemini_api_key;

    // Start HTTPS connection
    if (https.begin(client, url)) {
      // Prepare JSON data
      StaticJsonDocument<200> doc;
      JsonArray contents = doc.createNestedArray("contents");
      JsonObject content = contents.createNestedObject();
      JsonArray parts = content.createNestedArray("parts");
      JsonObject part = parts.createNestedObject();
      part["text"] = "Imagine you're a humorous AI. Describe the feeling of the following weather. Your answer should be around 50 to 60 characters.\
       And only reply with the humorous sentence and nothing else. Weather info: " + String(weatherData);

      // Serialize JSON
      String jsonString;
      serializeJson(doc, jsonString);

      // Set headers
      https.addHeader("Content-Type", "application/json");

      // Make POST request
      int httpCode = https.POST(jsonString);

      // Check response
      if (httpCode > 0) {
        String payload = https.getString();
         // Parse Gemini response
        DynamicJsonDocument doc(1024);
        deserializeJson(doc, payload);
        JsonObject obj = doc["candidates"][0]["content"]["parts"][0];
        String text = obj["text"];
        
        Serial.println("Gemini Summary:");
        Serial.println(text);

        // split the text into 3 parts
        int len = text.length();
        int part1_end = len / 3;
        int part2_end = 2 * len / 3;

        String part1 = text.substring(0, part1_end);        // First third
        String part2 = text.substring(part1_end, part2_end); // Second third
        String part3 = text.substring(part2_end);            // Third part

        display_text(part1, part2, part3);

      } else {
        Serial.println("Error on HTTP request");
      }

      https.end();
    } else {
      Serial.println("HTTPS connection failed");
     }
  }
}

void setup() {
  Serial.begin(115200);
  u8g2.begin();
  WiFi.begin(ssid, password);

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

  Serial.println("Connected to WiFi");
  
  // Run immediately after setup
  delay(30000); //start with a 30 second delay
  fetchAndProcessData();
  previousMillis = millis();  // Update the timer
}

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

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    fetchAndProcessData();
  }
  delay(1000);
}