#include <maps/wikimap/mapspro/libs/sender/include/campaign_achieve_edits.h>
#include "json_util.h"
#include <yandex/maps/wiki/common/misc.h>

namespace maps::wiki::sender {

using namespace std::literals::string_literals;

SubCampaignAchieveEdits SubCampaignAchieveEdits::fromJson(const json::Value& json)
{
    assertJsonObjectHasFields(json, {"nick", "edits", "slugs"});

    SubCampaignAchieveEdits res;
    res.nick = json["nick"].as<std::string>();
    res.edits = json["edits"].as<std::vector<int>>();
    res.slugs = LocalizedString::fromJson(json["slugs"]);
    return res;
}

NotExistingCampaignAchieveEditsError::NotExistingCampaignAchieveEditsError(int edits, const Lang& lang) :
    RuntimeError(
        "Achieve edits campaign for "s +
        "edits '"s + std::to_string(edits) + "' and "s
        "lang '"s + lang + "' doesn't exist"s
    )
{}

CampaignAchieveEdits::CampaignAchieveEdits(std::string name, SubCampaignsAchieveEdits subCampaigns) :
    name_(std::move(name)), subCampaigns_(std::move(subCampaigns))
{}

CampaignAchieveEdits CampaignAchieveEdits::fromJson(const json::Value& json)
{
    assertJsonObjectHasFields(json, {"name", "sub-campaigns"});

    auto parseSubCampaigns = [](const json::Value& subCampaignsJson){
        ASSERT(subCampaignsJson.isArray());
        SubCampaignsAchieveEdits subCampaigns;
        for (const auto& subCampaignJson : subCampaignsJson) {
            subCampaigns.emplace_back(SubCampaignAchieveEdits::fromJson(subCampaignJson));
        };
        return subCampaigns;
    };

    return CampaignAchieveEdits(
        json["name"].as<std::string>(),
        parseSubCampaigns(json["sub-campaigns"])
    );
}

const std::string& CampaignAchieveEdits::getName() const
{
    return name_;
}

const CampaignSlug& CampaignAchieveEdits::getCampaignSlug(int edits, const Lang& lang) const
{
    for (const auto& subCampaign : subCampaigns_) {
        if (common::isIn(edits, subCampaign.edits) && subCampaign.slugs.isLangExists(lang)) {
            return subCampaign.slugs.getForLang(lang);
        }
    }
    throw NotExistingCampaignAchieveEditsError(edits, lang);
}

} // namespace maps::wiki::sender
