#include <maps/wikimap/mapspro/services/editor/src/user_context.h>

#include <maps/wikimap/mapspro/services/editor/src/acl_utils.h>
#include <maps/wikimap/mapspro/services/editor/src/branch_helpers.h>
#include <maps/wikimap/mapspro/services/editor/src/exception.h>

#include <maps/wikimap/mapspro/libs/acl_utils/include/moderation.h>
#include <maps/wikimap/mapspro/libs/social/include/yandex/maps/wiki/social/gateway.h>

namespace maps::wiki {

UserContext::UserContext(TUid uid, std::string_view userRealIp, std::optional<uint16_t> port)
    : uid_(uid)
    , userRealIp_(userRealIp)
    , port_(std::move(port))
{
    CHECK_REQUEST_PARAM(uid);
}

const acl::User& UserContext::aclUser(const BranchContext& branchContext)
{
    if (!cachedUserData_ || &branchContext != &cachedUserData_->branchContext) {
        cachedUserData_ = std::make_shared<CachedUserData>(branchContext);
    }

    if (!cachedUserData_->user) {
        cachedUserData_->user.emplace(getUser(branchContext, uid_));
    }
    return *cachedUserData_->user;
}

const std::string& UserContext::moderationStatus(const BranchContext& branchContext)
{
    if (!cachedModerationStatus_) {
        acl::ACLGateway aclGw(branchContext.txnCore());
        const auto& user = aclUser(branchContext);
        cachedModerationStatus_ =
            std::make_shared<std::string>(acl_utils::moderationStatus(aclGw, user));
    }
    return *cachedModerationStatus_;
}

void UserContext::saveActivity(
    const BranchContext& branchContext,
    social::UserActivityAction action,
    const std::optional<TId>& entityId) const
{
    if (!userRealIp_.empty()) {
        social::Gateway gateway(branchContext.txnSocial());
        gateway.saveUserActivity(uid_, userRealIp_, port_, action, entityId);
    }
}

} // namespace maps::wiki
