#pragma once

#include <dbus/api/api.h>
#include <dbus/dBus.h>
#include <filesystem>

namespace api::project
{
//--------------------------------------------------------------
enum class OperationType : uint8_t
{
  Create = 0,
  Open,
  Save,
  SaveAs,
  Close,
};
//--------------------------------------------------------------

/* --- */

//--------------------------------------------------------------
struct ProjectOperationEvent : dBus::api::DefaultData<dBus::makeID("project.file.operation")>
{
  ProjectOperationEvent()                                                = default;     // Default constructor
  virtual ~ProjectOperationEvent()                                       = default;     // Default destructor
  ProjectOperationEvent(const ProjectOperationEvent &obj)                = default;     // Copy constructor
  ProjectOperationEvent(ProjectOperationEvent &&obj) noexcept            = default;     // Move constructor
  ProjectOperationEvent &operator=(const ProjectOperationEvent &obj)     = default;     // Copy assignment operator
  ProjectOperationEvent &operator=(ProjectOperationEvent &&obj) noexcept = default;     // Move assignment operator

  OperationType         operationType;
  std::filesystem::path filePath;

  [[nodiscard]] std::string toString() const override
  {
    if (operationType == OperationType::Open || operationType == OperationType::SaveAs)
      return std::format("ProjectOperationEvent: operation={}, filePath={}", getOperationString(), filePath.string());
    else
      return std::format("ProjectOperationEvent: operation={}", getOperationString());
  }

  private:
  [[nodiscard]] std::string getOperationString() const
  {
    switch (operationType)
    {
      using enum OperationType;
      case Create:
        return "Create";
      case Open:
        return "Open";
      case Save:
        return "Save";
      case SaveAs:
        return "SaveAs";
      case Close:
        return "Close";
    }
    throw std::runtime_error("Invalid project operation");
  }
};
//--------------------------------------------------------------
inline dBus::api::PostReturnStatus postProjectOperationRequest(dBus::Bus &bus, const OperationType &operationType, const std::filesystem::path &filePath = "")
{
  auto eventData          = ProjectOperationEvent();
  eventData.operationType = std::move(operationType);
  eventData.filePath      = std::move(filePath);

  return dBus::api::requestData<decltype(eventData), void>(bus, eventData.getID(), eventData, dBus::MessageCategory::UI);
}
//--------------------------------------------------------------
using ProjectOperationMessage_ptr = std::shared_ptr<dBus::RequestMessage<ProjectOperationEvent, void>>;
}     // namespace api::project
