#include "mission/mission_enqueue.hpp"

namespace lm {

nlohmann::json MissionEnqueue::normalizeParameters(const nlohmann::json& parameters)
{
  if (parameters.is_object())
    return parameters;
  if (!parameters.is_array())
    return nlohmann::json::object();

  nlohmann::json out = nlohmann::json::object();
  for (const auto& item : parameters)
  {
    if (!item.is_object())
      continue;
    if (item.contains("id") && item.contains("value"))
      out[item["id"].get<std::string>()] = item["value"];
    else if (item.contains("key") && item.contains("value"))
      out[item["key"].get<std::string>()] = item["value"];
  }
  return out;
}

bool MissionEnqueue::buildPayload(const MissionStore& store,
                                  const nlohmann::json& request,
                                  nlohmann::json& payload,
                                  std::string& err)
{
  if (!request.is_object())
  {
    err = "request must be an object";
    return false;
  }

  nlohmann::json mission;
  if (request.contains("mission") && request["mission"].is_object())
  {
    mission = request["mission"];
  }
  else if (request.contains("mission_id") && request["mission_id"].is_string())
  {
    const auto found = store.findMission(request["mission_id"].get<std::string>());
    if (!found)
    {
      err = "mission not found";
      return false;
    }
    mission = *found;
  }
  else
  {
    err = "mission or mission_id is required";
    return false;
  }

  payload = nlohmann::json::object();
  payload["mission"] = mission;
  payload["parameters"] = request.contains("parameters") ? normalizeParameters(request["parameters"])
                                                         : nlohmann::json::object();
  if (request.contains("priority") && request["priority"].is_number())
    payload["priority"] = request["priority"];
  if (request.contains("robot_id") && request["robot_id"].is_string())
    payload["robot_id"] = request["robot_id"];
  if (request.contains("source") && request["source"].is_string())
    payload["source"] = request["source"];
  else if (request.contains("message") && request["message"].is_string())
    payload["source"] = request["message"].get<std::string>();
  return true;
}

}  // namespace lm
