#include "edits.h"

#include <maps/wikimap/mapspro/services/tasks_social/src/assessment_sampler/lib/common.h>

#include <maps/wikimap/mapspro/libs/common/include/yandex/maps/wiki/common/robot.h>
#include <maps/wikimap/mapspro/libs/configs_editor/include/yandex/maps/wiki/configs/editor/category_groups.h>
#include <maps/wikimap/mapspro/libs/configs_editor/include/yandex/maps/wiki/configs/editor/config_holder.h>
#include <maps/wikimap/mapspro/libs/revision/include/yandex/maps/wiki/revision/common.h>

#include <fmt/format.h>


namespace maps::wiki::assessment::sampler {

namespace {

using namespace fmt::literals;

const std::string SERVICE_GROUP = "service_group";
const std::string JC_SUFFIX = "_jc";
const std::string OBJECT_DELETED = "object-deleted";

bool isServiceCategory(const std::string& categoryId) {
    static const auto serviceCategories = configs::editor::ConfigHolder()
        .categoryGroups()
        .categoryIdsByGroup(SERVICE_GROUP);

    return serviceCategories.count(categoryId);
}

bool isJunctionRemoval(const std::string& categoryId, const std::string& action)
{
    return categoryId.ends_with(JC_SUFFIX) && action == OBJECT_DELETED;
}

} // namespace

GroupNameToUnits loadEditsUnits(
    social::Gateway& gateway,
    chrono::TimePoint timepointMin,
    chrono::TimePoint timepointMax,
    const TUids& allowedUids)
{
    const auto events = gateway.loadNoTaskEditsByCreationInterval(
        social::DateTimeCondition(timepointMin, timepointMax));

    GroupNameToUnits result;
    for (const auto& event : events) {
        const auto categoryId = event.getPrimaryObjectCategory();
        const auto createdBy = event.createdBy();

        if (categoryId && isServiceCategory(*categoryId)) {
            continue;
        }
        if (categoryId && isJunctionRemoval(*categoryId, event.action())) {
            continue;
        }
        if (common::isRobot(createdBy) || !allowedUids.contains(createdBy)) {
            continue;
        }
        if (event.commitData()->branchId() != maps::wiki::revision::TRUNK_BRANCH_ID) {
            continue;
        }

        const std::string groupName = fmt::format(
            "{category}-{created_by}",
            "category"_a = categoryId ? *categoryId : COMMON,
            "created_by"_a = createdBy
        );

        result[groupName].emplace_back(Unit{
            .id = UNKNOWN_UNIT_ID,
            .entity = {
                .id = std::to_string(event.commitData()->commitId()),
                .domain = Entity::Domain::Edits
            },
            .action = {
                .name = event.action(),
                .by = createdBy,
                .at = chrono::parseSqlDateTime(event.createdAt())
            }
        });
    }
    return result;
}

} // maps::wiki::assessment::sampler
