#include "requirementTreeModel.h"

using namespace std;
using namespace gui;
//--------------------------------------------------------------
/* Constructor */
RequirementTreeModel::RequirementTreeModel(dBus::Bus &bus)
  : m_bus(bus)
{
}
//--------------------------------------------------------------
void RequirementTreeModel::GetValue(wxVariant &variant, const wxDataViewItem &item, const unsigned col) const
{
  // Sanity check
  if (!item.IsOk())
    return;

  const auto *data = static_cast<RequirementData *>(item.GetID());
  if (!data)
    return;

  // Return the appropriate value based on the column index
  switch (col)
  {
    case 0:     // ID column
      variant = data->id;
      break;
    case 1:     // Title column
      variant = data->title;
      break;
    default:
      break;
  }
}
//--------------------------------------------------------------
bool RequirementTreeModel::SetValue(const wxVariant &variant, const wxDataViewItem &item, unsigned col)
{
  return {};
}
//--------------------------------------------------------------
wxDataViewItem RequirementTreeModel::GetParent(const wxDataViewItem &item) const
{
  if (!item.IsOk())
    return wxDataViewItem(nullptr);

  // Get the requirement data associated with the item
  const auto *data = static_cast<RequirementData *>(item.GetID());
  if (!data)
    return wxDataViewItem(nullptr);     // If the item is invalid, return an invalid item
  if (data == &m_rootRequirement)
    return wxDataViewItem(nullptr);     // If the item is the root requirement, return an invalid item
  if (!data->parent)
    return wxDataViewItem(nullptr);     // If the item has no parent, return an invalid item

  return wxDataViewItem(data->parent);
}
//--------------------------------------------------------------
bool RequirementTreeModel::IsContainer(const wxDataViewItem &item) const
{
  const auto *data = static_cast<RequirementData *>(item.GetID());
  if (!data)
    return true;

  return !data->children.empty();     // An item is a container if it has children
}
//--------------------------------------------------------------
bool RequirementTreeModel::HasContainerColumns(const wxDataViewItem &wxDataViewItem) const
{
  return true;
}
//--------------------------------------------------------------
unsigned int RequirementTreeModel::GetChildren(const wxDataViewItem &item, wxDataViewItemArray &children) const
{
  const auto *data = static_cast<RequirementData *>(item.GetID());
  if (!data)     // If the item is invalid, return the root requirement as the only child
  {
    children.Add(wxDataViewItem(const_cast<RequirementData *>(&m_rootRequirement)));
    return 1;
  }

  // Add the children of the current item to the children array
  for (const auto &child : data->children)
  {
    children.Add(wxDataViewItem(child.get()));
  }
  return static_cast<uint32_t>(data->children.size());
}
//--------------------------------------------------------------
void RequirementTreeModel::loadRootRequirement()
{
  // Get the root requirements from dBus
  try
  {
    const auto ret = api::requirement::postGetRequirementRequest(m_bus);
    if (!ret)
    {
      wxMessageBox("No manager found for requirement request.\n\n"
                   "Error loading root requirements.",
                   "Error",
                   wxOK | wxICON_ERROR);
      return;
    }

    m_rootRequirement = RequirementData(*ret);
  }
  catch (const std::exception &e)
  {
    // Handle the error (e.g., log it, show a message to the user, etc.)
    // For now, we just print the error message to the console
    std::cerr << "Error loading root requirements: " << e.what() << std::endl;
    return;
  }

  // Notify the control that the data has changed
  //ItemChanged(wxDataViewItem(nullptr));     // Notify that the entire tree has changed
  //ItemsAdded(wxDataViewItem(nullptr), wxDataViewItemArray{ wxDataViewItem(&m_rootRequirement) });
  Cleared();
}
//--------------------------------------------------------------
RequirementData *RequirementTreeModel::AddChildRequirement(RequirementData *parent, std::unique_ptr<RequirementData> requirementData)
{
  return {};
}
//--------------------------------------------------------------
void RequirementTreeModel::clear()
{
}
//--------------------------------------------------------------
RequirementData *RequirementTreeModel::GetRequirementData(const wxDataViewItem &item) const
{
  return {};
}
//--------------------------------------------------------------
