#pragma once

#include <Arduino.h>

struct SenderStateMachineConfig {
  uint16_t short_id;
  const char *device_id;
};

struct SenderStats {
  uint8_t queue_depth;
  uint8_t build_count;
  uint16_t inflight_batch_id;
  uint16_t last_sent_batch_id;
  uint16_t last_acked_batch_id;
  uint8_t retry_count;
  bool ack_pending;
  uint32_t ack_timeout_total;
  uint32_t ack_retry_total;
  uint32_t ack_miss_streak;
  uint32_t rx_window_ms;
  uint32_t sleep_ms;
};

class SenderStateMachine {
public:
  bool begin(const SenderStateMachineConfig &config);
  void loop();
  SenderStats stats() const;

private:
  enum class State : uint8_t {
    Syncing = 0,
    Normal = 1,
    Catchup = 2,
    WaitAck = 3
  };

  void handleMeterRead(uint32_t now_ms);
  void maybeSendBatch(uint32_t now_ms);
  void handleAckWindow(uint32_t now_ms);
  bool applyTimeFromAck(uint8_t time_valid, uint32_t ack_epoch);
  void validateInvariants();
};
