#ifndef ASYNC_NETWORK_H
#define ASYNC_NETWORK_H

#include <WiFi.h>
#include <functional>
#include <time.h>

// Callback types
typedef std::function<void()> NetworkCallback;

// Non-blocking WiFi reset state machine
enum class WiFiResetState : uint8_t {
  IDLE,
  WIFI_OFF,       // WiFi turned off, waiting before turning on
  WIFI_ON,        // WiFi turned on, waiting before connecting
  CONNECTING      // WiFi.begin() called, waiting for result
};

class AsyncNetwork {
  friend void ntpSyncCallback(struct timeval *tv);

public:
  AsyncNetwork();

  void begin(bool forceConfig = false);
  void update(bool allowBlockingChecks = true);

  // Callbacks
  void onConnected(NetworkCallback cb) { _onConnected = cb; }
  void onDisconnected(NetworkCallback cb) { _onDisconnected = cb; }
  void onTimeSync(NetworkCallback cb) { _onTimeSync = cb; }
  void onAPMode(NetworkCallback cb) { _onAPMode = cb; }

  // Status
  bool isConnected() { return WiFi.status() == WL_CONNECTED; }
  bool hasTime() { return _hasTime; }
  bool isHealthy();
  String getIP() { return WiFi.localIP().toString(); }
  int getRSSI() { return _signalStrength; }
  int getConsecutiveFailures() { return _consecutiveFailures; }
  void updateActivity() {
    _lastValidActivity = millis();
  } // Call on web requests

  // TWT (WiFi 6 power saving)
  bool isTWTActive() { return _twtActive; }
  void enableTWT();
  void disableTWT();

  // External failure reporting
  void reportNetworkFailure();
  void reportNetworkSuccess();

  // Weather (Sunrise/Sunset for Automations)
  void fetchWeatherIfNeeded();
  uint32_t getSunriseTime() { return _sunriseTime; }
  uint32_t getSunsetTime() { return _sunsetTime; }

  // Time
  const char *getFormattedTime();
  int getHour();
  int getMinute();

private:
  bool _connected;
  bool _hasTime;
  bool _portalRunning;

  String _apName;

  unsigned long _lastNtpCheck;
  unsigned long _lastSignalCheck;
  unsigned long _lastConnectivityCheck;
  unsigned long _lastReconnectAttempt;

  unsigned long _lastValidActivity;
  unsigned long _lastWeatherFetch;
  uint32_t _sunriseTime;
  uint32_t _sunsetTime;
  int _signalStrength;
  int _consecutiveFailures;
  int _backoffMultiplier;

  bool _twtActive;

  // Non-blocking WiFi reset state machine
  WiFiResetState _resetState;
  unsigned long _resetStartTime;

  NetworkCallback _onConnected;
  NetworkCallback _onDisconnected;
  NetworkCallback _onAPMode;
  NetworkCallback _onTimeSync;

  void handleWiFiEvents();
  void handleNTPSync();
  void startNTP();
  bool tryHttpTimeSync();
  void updateSignalStrength();
  void setupWiFiEventHandlers();
  void checkConnectivity(bool allowBlockingChecks);
  bool checkInternetConnectivity();
  void reapplyStabilitySettings();
  void connectWithCredentials();

  int _consecutiveInternetFailures = 0;
};

extern AsyncNetwork network;

#endif
