#pragma once

#include "common.h"
#include "email_params_rendering.h"

#include <yandex/maps/wiki/common/geom.h>
#include <yandex/maps/wiki/tasks/task_logger.h>
#include <yandex/maps/wiki/revision/common.h>
#include <yandex/maps/wiki/revision/commit.h>

#include <maps/wikimap/mapspro/libs/sender/include/gateway.h>

#include <chrono>
#include <set>

namespace maps::wiki::releases_notification {

const size_t DEFAULT_COMMITS_COUNT = 0;

class VecUserData
{
public:
    explicit VecUserData()
        : commitsCount_(DEFAULT_COMMITS_COUNT)
        , sinceTimePoint_(chrono::TimePoint::max())
        , tillTimePoint_(chrono::TimePoint::min())
    {}

    size_t getCommitsCount() const { return commitsCount_; }
    void addCommit() { ++commitsCount_; }

    chrono::TimePoint sinceTimePoint() const { return sinceTimePoint_; }
    chrono::TimePoint tillTimePoint() const { return tillTimePoint_; }

    void setSinceTimePoint(chrono::TimePoint timePoint)
    { sinceTimePoint_ = timePoint; }

    void setTillTimePoint(chrono::TimePoint timePoint)
    { tillTimePoint_ = timePoint; }

private:
    size_t commitsCount_;
    chrono::TimePoint sinceTimePoint_;
    chrono::TimePoint tillTimePoint_;
};

struct VecReleaseData
{
    explicit VecReleaseData()
        : firstCommitAt(chrono::TimePoint::max())
        , lastCommitAt(chrono::TimePoint::min())
    {}

    std::map<revision::UserID, VecUserData> commitedUsers;
    chrono::TimePoint firstCommitAt;
    chrono::TimePoint lastCommitAt;
};

VecReleaseData getVecReleaseData(
    pqxx::transaction_base& txnCore,
    pqxx::transaction_base& txnSocial,
    Mode mode);

std::set<revision::UserID> getSatReleaseUsers(
    pqxx::transaction_base& txnCore,
    pqxx::transaction_base& txnSocial,
    const common::Geom& releaseGeom);

std::set<revision::UserID> getContributorUsers(
    pqxx::transaction_base& txncore);

std::set<revision::UserID> getActiveContributorUsers(
    pqxx::transaction_base& txnCore,
    size_t minCorrectionsCount,
    size_t maxSilentPeriodDays);


using UidToSpecificParamsPtr = std::map<revision::UserID, std::unique_ptr<ITypeSpecificParams>>;

struct ReleaseInfo
{
    UidToSpecificParamsPtr uidToParams;
    std::unique_ptr<ITypeSpecificParams> defaultParams;
};

ReleaseInfo
findUsersToNotify(
    const TaskParams& params,
    PgPools& pgPools,
    tasks::TaskPgLogger& logger);


} // maps::wiki::releases_notification
