#pragma once

#include "sensors_feature_positioner.h"
#include "types.h"

#include <maps/wikimap/mapspro/services/mrc/libs/config/include/config.h>

#include <string>

namespace maps::mrc::sensors_feature_positioner {

class SensorsFeaturePositionerPool {
public:
    // Creates positioners for each track of the assignmentId
    SensorsFeaturePositionerPool(
        mds::Mds& mdsClient,
        pgpool3::Pool& pool,
        const adapters::Matcher& graphMatcher,
        db::TId assignmentId,
        db::TrackPoints /* sink */);

    // Creates positioners for each track of the sourceId in the
    // provided time range
    SensorsFeaturePositionerPool(
        mds::Mds& mdsClient,
        pgpool3::Pool& pool,
        const adapters::Matcher& graphMatcher,
        const std::string& sourceId,
        chrono::TimePoint minTime,
        chrono::TimePoint maxTime);

    // returns the position if the timepoint
    // belongs to one of the tracks of the pool
    std::optional<pos_improvment::ImprovedGpsEvent> getPositionByTime(
        const std::string& sourceId,
        chrono::TimePoint time) const;

    // returns the feature with the modified position if the feature
    // belongs to one of the tracks of the pool
    std::optional<db::Feature> calculatePosition(db::Feature feature) const;

    // modifies features positions for each feature that belongs to one
    // of the tracks of the pool
    void applyPositionIfPossible(db::Features& features) const;

    void applyPositionIfPossible(db::Features::iterator, db::Features::iterator) const;
private:
    void addPositioners(const std::string& sourceId,
                        const Tracks& tracks,
                        const adapters::Matcher& graphMatcher);

private:
    // feature positioners for each sourceId sorted by track time
    std::unordered_map<std::string,
                       SensorsFeaturePositioners> featurePositionersBySourceId_;
};

} // namespace maps::mrc::sensors_feature_positioner
