#pragma once

#include "mission/mission_queue.hpp"
#include "mission/mission_store.hpp"

#include <atomic>
#include <functional>
#include <mutex>
#include <optional>
#include <string>
#include <thread>
#include <unordered_map>

namespace lm {

class ModbusTriggerService
{
public:
  using EnqueueFn = std::function<bool(const nlohmann::json& request, std::string& err)>;

  ModbusTriggerService(MissionStore& store, EnqueueFn enqueue_fn, int tcp_port = 5502);
  ~ModbusTriggerService();

  ModbusTriggerService(const ModbusTriggerService&) = delete;
  ModbusTriggerService& operator=(const ModbusTriggerService&) = delete;

  nlohmann::json coilStates() const;
  bool writeCoil(int coil_id, bool value, std::string& err);
  bool fireCoil(int coil_id, std::string& err);

private:
  MissionStore& store_;
  EnqueueFn enqueue_fn_;
  int tcp_port_;

  mutable std::mutex mu_;
  std::unordered_map<int, bool> coils_;

  std::atomic<bool> stop_{false};
  std::thread tcp_thread_;

  void tcpLoop();
  void handleTcpClient(int client_fd);
};

}  // namespace lm
