#pragma once

#include <maps/wikimap/mapspro/libs/social_serv_serialize/include/task_extended.h>
#include <maps/wikimap/mapspro/services/social/src/libs/common/common.h>
#include <maps/wikimap/mapspro/services/social/src/libs/feedback/feed_for_ui.h>
#include <maps/wikimap/mapspro/services/social/src/libs/feedback/operations.h>
#include <maps/wikimap/mapspro/services/social/src/libs/feedback/presets.h>
#include <maps/wikimap/mapspro/services/social/src/libs/feedback/regions.h>
#include <maps/wikimap/mapspro/services/social/src/libs/feedback/stats.h>
#include <yandex/maps/wiki/social/feedback/aggregated_counter.h>
#include <yandex/maps/wiki/social/feedback/enums.h>
#include <yandex/maps/wiki/social/feedback/preset.h>
#include <yandex/maps/wiki/social/feedback/task_aoi.h>
#include <yandex/maps/wiki/social/feedback/task_feed.h>

#include <maps/libs/json/include/value.h>

namespace maps::wiki::social::feedback {

void json(
    const Preset& preset,
    json::ObjectBuilder builder);

} // namespace maps::wiki::social::feedback

namespace maps::wiki::socialsrv {

template<typename Collection>
void collectionToJsonArray(
    maps::json::ArrayBuilder builder,
    const Collection& collection)
{
    std::vector<std::string> strings;
    std::transform(
        collection.begin(), collection.end(), std::back_inserter(strings),
        [](const auto& val) { return boost::lexical_cast<std::string>(val); }
    );

    builder.putRange(strings.begin(), strings.end());
}

void jsonize(json::ArrayBuilder& arrayBuilder,
    const social::feedback::TypeCatToTypes& typeCatToTypes);

void json(
    const AoiRegion& region,
    json::ObjectBuilder builder);

// TODO: add Response class for each handle
// and serialize them instead of their internals
//
std::string toJson(const AoiRegionToTaskCounters& regionsToCounters);

std::string toJson(const TaskFeedForUI& feed, UserId uid);

std::string toJson(const std::vector<social::feedback::Type>& types);

std::string toJson(const std::set<std::string>& sources);

std::string toJson(const RegionsStatRows& regionStatRows, UserId uid);

std::string toJson(
    const social::feedback::Preset& preset, const std::string& token);

std::string toJson(const social::feedback::Presets& presets);

std::string toJson(const std::string& token);

std::string toJson(
    const serialize::TaskExtended& taskExtended,
    const std::string& token,
    UserId uid);

std::string toJson(
    const serialize::TaskExtended& taskExtended,
    UserId uid);

std::string toJson(
    const std::vector<social::feedback::AggregatedCounter>& counters);

std::string toJson(const PaidOperationCounters& paidOperationCounters);

template<typename T>
std::vector<T> asVector(const json::Value& array)
{
    std::vector<T> res;
    for (const auto& element : array) {
        res.push_back(boost::lexical_cast<T>(element.toString()));
    }
    return res;
}

std::string toJson(const AssignedPresetsResponse& assignedPresetsResponse);

} // maps::wiki::socialsrv
