#include "track_loader.h"
#include "types.h"

#include <maps/wikimap/mapspro/services/mrc/libs/db/include/track_point_gateway.h>
#include <maps/wikimap/mapspro/services/mrc/libs/position_improvment/include/position_improvment.h>
#include <maps/libs/log8/include/log8.h>

#include <vector>

namespace maps::mrc::tracks_with_sensors {

db::TrackPoints loadTrack(
    wiki::common::PoolHolder& poolHolder,
    db::TId assignmentId,
    chrono::TimePoint minTime,
    chrono::TimePoint maxTime)
{
    auto txn = poolHolder.pool().slaveTransaction();
    db::TrackPointGateway tpGtw(*txn);
    db::TrackPoints assignmentTrackPoints = tpGtw.load(
        db::table::TrackPoint::assignmentId.equals(assignmentId));
    REQUIRE(assignmentTrackPoints.size() > 0, "NO track points");

    db::TrackPoints trackPoints;
    trackPoints.reserve(assignmentTrackPoints.size());
    for (auto point : assignmentTrackPoints) {
        if (point.timestamp() >= minTime
            && point.timestamp() <= maxTime)
        {
            trackPoints.push_back(point);
        }
    }

    if (trackPoints.empty()) {
        return trackPoints;
    }

    std::sort(trackPoints.begin(), trackPoints.end(),
              [](const db::TrackPoint& lhs, const db::TrackPoint& rhs) {
                  return lhs.timestamp() < rhs.timestamp();
              });

    db::TrackPoints filteredTrackPoints{trackPoints[0]};
    for(size_t i = 1; i < trackPoints.size(); i++) {
        if (trackPoints[i].timestamp() != filteredTrackPoints.back().timestamp()) {
            filteredTrackPoints.push_back(trackPoints[i]);
        }
    }

    INFO() << "loaded " << filteredTrackPoints.size() << "trackPoints";
    return filteredTrackPoints;
}

} // namespace maps::mrc::tracks_with_sensors
