#pragma once

#include "eventBus/eventBus.h"

#include <thread>

// Forward declarations
namespace core
{
class Context;
}
namespace gui
{
class MainFrame;
}

// UI event handler
namespace gui
{
//--------------------------------------------------------------
class UiEventHandler : public eventBus::Node
{
  friend class MainFrame;

  using json = nlohmann::ordered_json;

  public:
  UiEventHandler() = delete;                                             // Default constructor
  virtual ~UiEventHandler();                                             // Default destructor
  UiEventHandler(const UiEventHandler &obj)                = delete;     // Copy constructor
  UiEventHandler(UiEventHandler &&obj) noexcept            = delete;     // Move constructor
  UiEventHandler &operator=(const UiEventHandler &obj)     = delete;     // Copy assignment operator
  UiEventHandler &operator=(UiEventHandler &&obj) noexcept = delete;     // Move assignment operator

  explicit UiEventHandler(MainFrame &owner, core::Context &ctx);     // Constructor

  // Post a message to the UI with a specific topic and payload
  void postEventMessage(const std::string &topic,
                        const json        &payload) const;

  // Post a response message to the UI with a specific topic, request ID, status, and payload
  void postResponseMessage(const std::string &topic,
                           const std::string &requestId,
                           bool               isOk    = false,
                           const json        &payload = {}) const;

  protected:
  void processIncomingMessage(const json &message);           // Process incoming messages from the UI
  void processOutgoingMessage(const json &message) const;     // Process outgoing messages to the UI

  MainFrame     &m_owner;     // Reference to the main frame
  core::Context &m_ctx;       // Application context

  std::jthread m_thread;

  private:
  void startEventThread();                                  // Start the event handling thread
  void stopEventThread();                                   // Stop the event handling thread
  void processEvents(const std::stop_token &stopToken);     // Event processing loop
};
//--------------------------------------------------------------
}     // namespace gui
