#pragma once

#include <api/requirement.h>
#include <dBus/dBus.h>
#include <filesystem>
#include <wx/dataview.h>
#include <wx/wx.h>

namespace gui
{
//--------------------------------------------------------------
struct RequirementData
{
  std::string id;
  std::string title;

  RequirementData                              *parent = nullptr;
  std::vector<std::unique_ptr<RequirementData>> children;

  RequirementData()
  {
    id    = "badID";
    title = "badTITLE";
  }
  RequirementData(const api::requirement::Requirement &requirement)
  {
    id    = "testID";
    title = "testTITLE";
  }

  // Adds a child requirement
  RequirementData *AddChild(std::unique_ptr<RequirementData> child)
  {
    child->parent = this;
    children.push_back(std::move(child));
    return children.back().get();
  }
};
//--------------------------------------------------------------

/* --- */

//--------------------------------------------------------------
class RequirementTreeModel : public wxDataViewModel
{
  public:
  RequirementTreeModel()                                               = delete;      // Default constructor
  virtual ~RequirementTreeModel()                                      = default;     // Default destructor
  RequirementTreeModel(const RequirementTreeModel &obj)                = delete;      // Copy constructor
  RequirementTreeModel(RequirementTreeModel &&obj) noexcept            = delete;      // Move constructor
  RequirementTreeModel &operator=(const RequirementTreeModel &obj)     = delete;      // Copy assignment operator
  RequirementTreeModel &operator=(RequirementTreeModel &&obj) noexcept = delete;      // Move assignment operator

  explicit RequirementTreeModel(dBus::Bus &bus);     // Constructor

  // wxDataViewModel overrides methods
  void GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned col) const override;
  bool SetValue(const wxVariant &variant, const wxDataViewItem &item, unsigned col) override;

  [[nodiscard]] wxDataViewItem GetParent(const wxDataViewItem &item) const override;
  [[nodiscard]] bool           IsContainer(const wxDataViewItem &item) const override;
  [[nodiscard]] bool           HasContainerColumns(const wxDataViewItem &) const override;

  unsigned int GetChildren(const wxDataViewItem &item, wxDataViewItemArray &children) const override;

  // Tree data model specific methods
  void loadRootRequirement();     // Add a root requirement to the tree

  RequirementData *AddChildRequirement(RequirementData *parent, std::unique_ptr<RequirementData> requirementData);     // Add a child requirement to a parent requirement
  void             clear();
  RequirementData *GetRequirementData(const wxDataViewItem &item) const;     // Get the requirement data associated with a given item

  protected:
  dBus::Bus &m_bus;     // Reference to the application bus

  // std::vector<std::unique_ptr<RequirementData>> m_rootRequirement;
  RequirementData m_rootRequirement;
};
//--------------------------------------------------------------
}     // namespace gui
