#pragma once

#include <maps/wikimap/mapspro/services/tasks_realtime/src/user_edits_metrics/lib/util.h>

#include <maps/wikimap/mapspro/libs/revision/include/yandex/maps/wiki/revision/commit.h>
#include <maps/wikimap/mapspro/libs/revision/include/yandex/maps/wiki/revision/common.h>
#include <maps/wikimap/mapspro/libs/social/include/yandex/maps/wiki/social/task.h>

#include <maps/libs/chrono/include/time_point.h>

#include <optional>
#include <unordered_map>

namespace maps::wiki::user_edits_metrics {

enum class UserType
{
    Common,
    Trusted,
    Yandex
};

using CommitIdToRegions = std::unordered_map<revision::DBID, revision::DBIDSet>;

class CommitData
{
public:
    CommitData(
        const revision::Commit& commit,
        const social::Task& task,
        UserType userType);

    // autoapproved commit
    CommitData(
        const revision::Commit& commit,
        UserType userType);

    void addRegionEvents(
        pqxx::transaction_base& txnViewTrunk,
        revision::DBID stableBranchId,
        const BranchesById& branchesById,
        const CommitIdToRegions& commitIdToRegions,
        const RegionsData& regionsData,
        const geolib3::BoundingBox& bbox);
    void addAoiRegions(const std::vector<std::string>& aoiNames);

    bool insideRegion(const std::string& regionName) const;

    std::optional<chrono::TimePoint> findEvent(
        const std::string& regionName,
        Event event) const;

    revision::DBID id() const { return id_; }
    UserType userType() const { return userType_; }
    chrono::TimePoint created() const { return created_; }
    bool inTrunk() const { return inTrunk_; }
    const std::set<std::string> regionsFromCommit() const { return regionsFromCommit_; }

private:
    revision::DBID id_;
    UserType userType_;
    chrono::TimePoint created_;
    EventToTime commonEvents_;
    RegionToEventToTime regionToEvents_;
    bool inTrunk_;
    std::set<std::string> regionsFromCommit_;
};

using CommitFilter = std::function<bool(const CommitData&)>;

EventToTime calcEventToTimeForBranchAndRegion(
    const BranchesById& branchesById,
    revision::DBID branchId,
    const std::string& regionName);
EventToTime calcEventToFirstDeployTime(const RegionToEventToTime& regionToEvents);

} // namespace maps::wiki::user_edits_metrics
