/*
 * AdvancedWiFiManagement.ino
 * 
 * This example demonstrates advanced WiFi management features of the
 * WiFiHandlerV2 class, including:
 * - Using event callbacks for connection events
 * - Using the watchdog to maintain connection
 * - Setting static IP configuration
 * - Power management settings
 */

#include "wifi-handlerv2.h"

// WiFi credentials
const char* ssid = "YourWiFiSSID";
const char* password = "YourWiFiPassword";

// Static IP configuration (if desired)
IPAddress staticIP(192, 168, 1, 200);     // ESP32 static IP
IPAddress gateway(192, 168, 1, 1);        // Router IP address
IPAddress subnet(255, 255, 255, 0);       // Subnet mask
IPAddress dns1(8, 8, 8, 8);               // Primary DNS (Google DNS)

// Create WiFiHandler instance
WiFiHandlerV2 wifi;

// Variables to track connection state
bool previouslyConnected = false;
unsigned long connectionStartTime = 0;
unsigned long totalConnectionTime = 0;
unsigned long disconnectionCount = 0;

void setup() {
  Serial.begin(115200);
  delay(1000);
  
  Serial.println("Starting Advanced WiFi Management example");
  
  // Set the hostname for easier identification on your network
  wifi.setHostname("esp32-advanced");
  
  // Register callback functions for connection events
  wifi.setOnConnectCallback(onWiFiConnect);
  wifi.setOnDisconnectCallback(onWiFiDisconnect);
  
  // Choose one of the following IP configuration methods:
  // 1. For DHCP (dynamic IP):
  wifi.setDHCP();
  
  // 2. For static IP (uncomment these lines and comment the setDHCP line):
  // Serial.println("Configuring static IP...");
  // wifi.setStaticIP(staticIP, gateway, subnet, dns1);
  
  // Enable the watchdog to maintain connection
  Serial.println("Enabling WiFi watchdog...");
  wifi.enableWatchdog(30000); // Check every 30 seconds
  
  // Connect to WiFi
  Serial.print("Connecting to WiFi network: ");
  Serial.println(ssid);
  
  if (wifi.connect(ssid, password)) {
    Serial.println("Initial connection successful!");
    
    // Configure power management
    // 1. For better power efficiency (might slightly impact responsiveness):
    // wifi.enablePowerSave();
    
    // 2. For better responsiveness (uses more power):
    wifi.disablePowerSave();
    
    connectionStartTime = millis();
  } else {
    Serial.println("Initial connection failed! The watchdog will try to reconnect.");
  }
}

void loop() {
  // Run wifi handler loop to maintain connection
  // This is critical for the watchdog functionality
  wifi.loop();
  
  // Your main application code here
  
  // Periodically display WiFi statistics
  static unsigned long lastStatsUpdate = 0;
  if (millis() - lastStatsUpdate > 10000) {
    displayWiFiStats();
    lastStatsUpdate = millis();
  }
  
  delay(100);
}

// WiFi connection callback
void onWiFiConnect() {
  Serial.println("\n*** WiFi CONNECTED ***");
  previouslyConnected = true;
  connectionStartTime = millis();
  
  // Print details about the connection
  printNetworkInfo();
}

// WiFi disconnection callback
void onWiFiDisconnect() {
  Serial.println("\n*** WiFi DISCONNECTED ***");
  
  if (previouslyConnected) {
    // Update statistics
    disconnectionCount++;
    totalConnectionTime += (millis() - connectionStartTime);
    previouslyConnected = false;
    
    Serial.println("The watchdog will attempt to reconnect automatically.");
  }
}

void printNetworkInfo() {
  Serial.println("===== Network Information =====");
  Serial.print("SSID: ");
  Serial.println(wifi.getSSID());
  
  Serial.print("IP Address: ");
  Serial.println(wifi.getIP());
  
  Serial.print("MAC Address: ");
  Serial.println(wifi.getMacAddress());
  
  Serial.print("Signal Strength (RSSI): ");
  Serial.print(wifi.getSignalStrength());
  Serial.println(" dBm");
  
  Serial.print("Signal Quality: ");
  Serial.print(wifi.getSignalQuality());
  Serial.println("%");
  Serial.println("==============================");
}

void displayWiFiStats() {
  Serial.println("\n===== WiFi Statistics =====");
  
  if (wifi.isConnected()) {
    Serial.println("Status: Connected");
    Serial.print("Connected to: ");
    Serial.println(wifi.getSSID());
    
    Serial.print("Current Signal Quality: ");
    Serial.print(wifi.getSignalQuality());
    Serial.println("%");
    
    // Calculate uptime for this session
    unsigned long currentSessionTime = millis() - connectionStartTime;
    
    // Convert to hours, minutes, seconds
    unsigned long secsCurrent = currentSessionTime / 1000;
    unsigned long minsCurrent = secsCurrent / 60;
    unsigned long hoursCurrent = minsCurrent / 60;
    secsCurrent %= 60;
    minsCurrent %= 60;
    
    Serial.print("Current Session Uptime: ");
    Serial.print(hoursCurrent);
    Serial.print("h ");
    Serial.print(minsCurrent);
    Serial.print("m ");
    Serial.print(secsCurrent);
    Serial.println("s");
  } else {
    Serial.println("Status: Disconnected");
    Serial.println("Attempting to reconnect...");
  }
  
  // Calculate total connection time
  unsigned long totalTime = totalConnectionTime;
  if (wifi.isConnected()) {
    totalTime += (millis() - connectionStartTime);
  }
  
  // Convert to hours, minutes, seconds
  unsigned long secsTotal = totalTime / 1000;
  unsigned long minsTotal = secsTotal / 60;
  unsigned long hoursTotal = minsTotal / 60;
  secsTotal %= 60;
  minsTotal %= 60;
  
  Serial.print("Total Connection Time: ");
  Serial.print(hoursTotal);
  Serial.print("h ");
  Serial.print(minsTotal);
  Serial.print("m ");
  Serial.print(secsTotal);
  Serial.println("s");
  
  Serial.print("Disconnection Count: ");
  Serial.println(disconnectionCount);
  
  Serial.println("===========================");
}