#pragma once

#include "outsource_region.h"

#include <yandex/maps/wiki/common/extended_xml_doc.h>
#include <yandex/maps/wiki/diffalert/revision/editor_config.h>
#include <yandex/maps/wiki/outsource/config.h>
#include <yandex/maps/wiki/revision/diff.h>
#include <yandex/maps/wiki/revision/revisionid.h>
#include <yandex/maps/wiki/common/tskv_logger.h>

#include <maps/libs/pgpool/include/pgpool3.h>
#include <maps/libs/st/include/st.h>

#include <unordered_map>

namespace maps {
namespace wiki {
namespace tasks {
namespace outsource_regions {

const size_t PUBSUB_CONSUMER_BATCH_SIZE = 50;

enum class YtEnabled { Yes, No };

class OutsourceRegionHandler
{
public:
    OutsourceRegionHandler(
        pgpool3::Pool& pool,
        const st::Configuration& stConfig,
        diffalert::EditorConfig editorConfig,
        outsource::Config outsourceConfig,
        std::string nproHost,
        Translator translator,
        YtEnabled ytEnabled);

    size_t dispatchNewCommits();

private:
    void onRegionCreated(
        OutsourceRegion& region,
        revision::DBID objectId,
        const revision::Commit& commit,
        const revision::AttributesDiff& attrsDiff,
        revision::UserID userId);
    void onRegionDeleted(
        OutsourceRegion& region,
        revision::DBID objectId,
        const revision::Commit& commit,
        revision::UserID userId);
    void onRegionAttrsChanged(
        OutsourceRegion& region,
        revision::DBID objectId,
        const revision::Commit& commit,
        const revision::AttributesDiff& attrsDiff,
        revision::UserID userId);
    void onRegionGeometryChanged(
        OutsourceRegion& region,
        revision::DBID objectId,
        const revision::Commit& commit,
        const revision::GeometryDiff& geomDiff);

    void createIssue(
        OutsourceRegion& region,
        revision::DBID commitId,
        revision::UserID userId);

    std::unordered_map<revision::DBID, OutsourceRegion> loadRegions(
        pqxx::transaction_base& txn,
        revision::DBID commitId,
        const std::set<revision::DBID>& objectIds);

    std::string findIssueKeyForRegion(revision::DBID objectId);

    void loadNewUsers(pqxx::transaction_base& txn, const std::set<revision::UserID>& userIds);
    const std::string& getLogin(revision::UserID userId) const;

    pgpool3::Pool& pool_;
    st::Gateway stGateway_;

    diffalert::EditorConfig editorConfig_;
    outsource::Config outsourceConfig_;
    std::string nproHost_;
    Translator translator_;
    YtEnabled ytEnabled_;

    common::TskvLogger actionsLogger_;
    common::TskvLogger paymentsLogger_;

    std::unordered_map<revision::UserID, std::string> userIdToLogin_;
};

} // namespace outsource_regions
} // namespace tasks
} // namespace wiki
} // namespace maps
