#ifndef STATUS_MONITOR_H
#define STATUS_MONITOR_H

#include <stdint.h>
#include <stdbool.h>
#include "midea_protocol.h"
#include "zigbee_zcl.h"
#include "uart_driver.h"

// Status monitoring configuration
typedef struct {
    uint32_t poll_interval_ms;    // How often to poll for status (default: 5000ms)
    uint32_t timeout_ms;          // Communication timeout per attempt (default: 1000ms)
    uint8_t max_retries;          // Maximum retry attempts before comm failure (default: 3)
} status_monitor_config_t;

// Status monitoring state
typedef struct {
    bool initialized;
    bool last_poll_success;
    uint32_t last_poll_time;      // Timestamp (ms) of last SUCCESSFUL poll
    uint32_t last_attempt_time;   // Timestamp (ms) of last poll attempt
    uint8_t retry_count;          // Consecutive failed attempts
    uint32_t error_count;         // Total accumulated communication errors
    bool comm_timeout;            // Watchdog tripped (retries exhausted / no response)
    bool fault_detected;          // AC reported an error_code or alarm_mask
    uint16_t fault_code;          // Last fault value (error_code | alarm_mask bits)
    status_monitor_config_t config;
    midea_status_t last_status;
    zcl_thermostat_attrs_t last_zcl_attrs;
} status_monitor_t;

// Initialize status monitor. If config is NULL, defaults are applied.
bool status_monitor_init(status_monitor_t *monitor, const status_monitor_config_t *config);

// Deinitialize status monitor
void status_monitor_deinit(status_monitor_t *monitor);

// Poll AC status via UART: sends a status request, receives and decodes the
// response, then updates internal state (fault detection, watchdog).
// current_time is the current monotonic time in milliseconds.
// Returns true on a successful poll, false on communication/decode failure.
bool status_monitor_poll(status_monitor_t *monitor, uart_driver_t *uart,
                         uint32_t current_time, midea_status_t *status);

// Process a raw UART response buffer (decode + fault detection + state update).
// Exposed separately so it can be exercised without live hardware.
// Returns true if the buffer decoded into a valid status.
bool status_monitor_process_response(status_monitor_t *monitor,
                                     const uint8_t *buffer, size_t length,
                                     uint32_t current_time, midea_status_t *status);

// Map MideaUART status to ZCL attributes
void status_monitor_map_to_zcl(const midea_status_t *status, zcl_thermostat_attrs_t *zcl_attrs);

// Watchdog: returns true if the time since the last successful poll exceeds the
// allowed window (poll_interval_ms + timeout_ms), or if the monitor has never
// polled successfully.
bool status_monitor_check_timeout(const status_monitor_t *monitor, uint32_t current_time);

// Handle a communication error: increments retry/error counters and trips the
// watchdog once max_retries is reached.
void status_monitor_handle_error(status_monitor_t *monitor);

// Returns true if the AC currently reports a fault.
bool status_monitor_has_fault(const status_monitor_t *monitor);

// Get last known status. Returns false on bad args.
bool status_monitor_get_last_status(const status_monitor_t *monitor, midea_status_t *status);

// Get last known ZCL attributes. Returns false on bad args.
bool status_monitor_get_last_zcl_attrs(const status_monitor_t *monitor, zcl_thermostat_attrs_t *zcl_attrs);

// Build a MideaUART status-request frame into buffer. Returns bytes written (0 on error).
size_t status_monitor_build_request(uint8_t *buffer, size_t buffer_size);

#endif // STATUS_MONITOR_H
