#pragma once

#include <api/requirement.h>
#include <memory>
#include <vector>

namespace core::project
{
class RequirementManager;
//--------------------------------------------------------------
class RequirementItem : public std::enable_shared_from_this<RequirementItem>
  , public api::requirement::Requirement
{
  using RequirementItemPtr = std::shared_ptr<RequirementItem>;

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

  explicit RequirementItem(RequirementManager                     &manager,     // Constructor
                           const std::shared_ptr<RequirementItem> &parentRequirement = nullptr);

  // Management functions
  [[nodiscard]] Requirement toRequirement() const;                      // Convert this requirement item to an api::requirement::Requirement struct and return it
  void                      update(const Requirement &updatedData);     // Update the data of this requirement item with the provided updated requirement data

  // Children management functions
  RequirementItemPtr                            getParent() const;                             // Get the m_parent requirement item of this requirement item
  void                                          appendChild(const Requirement &child);         // Append a child requirement item to this requirement item
  void                                          removeChild(const std::string &childUuid);     // Remove a child requirement item from this requirement item by its UUID
  void                                          removeChildren();                              // Remove all child requirement items from this requirement item
  [[nodiscard]] std::vector<RequirementItemPtr> getChildren() const;                           // Get the vector of child requirement items of this requirement item

  protected:
  RequirementManager             &m_requirementManager;     // Reference to the requirement manager that owns this requirement item
  std::weak_ptr<RequirementItem>  m_parent;                 // Weak pointer to the m_parent requirement item (nullptr for root)
  std::vector<RequirementItemPtr> m_children;               // Vector of shared pointers to child requirement items
};
//--------------------------------------------------------------
}     // namespace core::project
