#include "published_commits_data.h"

#include "grouper.h"

#include <maps/wikimap/mapspro/libs/gdpr/include/user.h>
#include <yandex/maps/wiki/social/profile_gateway.h>

namespace maps::wiki::notifications_dispatcher {


PublishedCommitsData::PublishedCommitsData(
    social::IProfileGateway& profileGateway,
    const std::list<revision::Commit>& commits
) {
    for (const auto& commit : commits) {
        const gdpr::User user(commit.createdBy());
        if (!user.hidden()) {
            usersCommitsCount_[user.uid()]++;
        }
    }

    auto usersVec = users();
    auto profiles = profileGateway.getUserProfiles(
        {usersVec.begin(), usersVec.end()}
    );

    for (const auto& profile : profiles) {
        usersLocales_[profile.uid()] = profile.locale();
    }
}

void PublishedCommitsData::merge(const std::vector<GroupedNotification>& groupedNotifications) {
    for (const auto& notification : groupedNotifications) {
        usersCommitsCount_[notification.uid] += notification.parameters["count"].as<size_t>();
    }
}

std::vector<int64_t> PublishedCommitsData::users() const {
    std::vector<int64_t> result;
    result.reserve(usersCommitsCount_.size());
    for (const auto& [uid, commits] : usersCommitsCount_) {
        result.push_back(uid);
    }
    return result;
}

std::vector<GroupedNotification>
PublishedCommitsData::groupedNotifications(const GroupInfo& groupInfo) const {
    std::vector<GroupedNotification> notifications;
    for (const auto& [uid, commits] : usersCommitsCount_) {
        auto localeIt = usersLocales_.find(uid);

        // FIXME: Temporarily launch only on users of "ru" locale
        if (localeIt == usersLocales_.end() || localeIt->second != "ru") {
            continue;
        }

        json::Builder paramsBuilder;
        // Structured binding are not variables, so cannot be captured
        paramsBuilder << [&,this,commits=commits](json::ObjectBuilder builder) {
            builder["count"] = commits;
            if (localeIt != usersLocales_.end()) {
                builder["locale"] = localeIt->second;
            }
        };

        notifications.emplace_back(
            uid,
            groupInfo.notificationType,
            groupInfo.groupKey,
            true,
            json::Value::fromString(paramsBuilder.str())
        );
    }

    return notifications;
}

}  // namespace maps::wiki::notifications_dispatcher
