#ifndef AUTOMATION_MANAGER_H
#define AUTOMATION_MANAGER_H

#include <Arduino.h>
#include <stdint.h>
#include <time.h>
#include "config.h"
#include <freertos/portmacro.h>

// Require this many consecutive "empty" readings before declaring room empty
#define PRESENCE_HYSTERESIS_COUNT 3

// Linked device is considered offline if no telemetry in this period
#define LINKED_DEVICE_ONLINE_TIMEOUT_MS 300000UL  // 5 minutes

class AutomationManager {
public:
  AutomationManager();

  void begin();
  void update();

  // Ingest telemetry from linked device via MQTT
  void updateLinkedDeviceTelemetry(bool motion, bool still, float cpuTemp, uint8_t switchMode, bool lightState);

  // Returns true if linked device has sent telemetry within LINKED_DEVICE_ONLINE_TIMEOUT_MS
  bool isLinkedDeviceOnline() const;

private:
  unsigned long _lastUpdate;
  
  // Rule Cooldowns / Timers
  unsigned long _lastNightLockRun;
  unsigned long _lastSunsetRun;
  unsigned long _lastHeatRun;
  
  // Presence Timers
  unsigned long _presenceEmptySince;
  unsigned long _presenceMotionSince;
  bool _presenceEmptyTriggered;
  bool _presenceMotionTriggered;
  
  // Morning Wake-Up State
  bool _morningActive;
  bool _morningAborted;  // Stays true until next day's window
  int32_t _morningStartPos;
  int32_t _morningLastSent;
  time_t _morningEndTime;

  // Telemetry state
  bool _hasLinkedDevice;
  bool _linkedMotion;
  bool _linkedStill;
  float _linkedCpuTemp;
  uint8_t _linkedMode;
  bool _linkedLightState;
  unsigned long _lastTelemetryTime;
  
  // Radar Suppression state
  bool _wasMoving;
  bool _suppressingSwitch;
  unsigned long _suppressEndTime;
  
  // Suppression ACK retry
  uint8_t _suppressionPendingMode;   // Mode we requested from linked switch
  uint8_t _suppressionRetryCount;    // How many retries remain
  unsigned long _suppressionLastRetry; // millis() of last retry attempt
  bool _suppressionAckPending;       // True while waiting for ACK
  
  // Presence hysteresis — require consecutive empty readings
  uint8_t _emptyReadingCount;
  
  // FIX #22: Spinlock protects shared telemetry state from concurrent access
  // between main loop (update()) and MQTT callback (updateLinkedDeviceTelemetry())
  portMUX_TYPE _telemetryMux = portMUX_INITIALIZER_UNLOCKED;

  void processNightLock();
  void processSunsetAutoClose();
  void processMorningWakeUp();
  void processPresence();
  void processHeatProtection();

  bool isTimeNow(uint8_t targetHour, uint8_t targetMinute, int offsetMinutes = 0);
  bool isDaytime();
};

extern AutomationManager automationManager;

#endif
