#pragma once

#include <maps/libs/geolib/include/direction.h>
#include <maps/libs/geolib/include/point.h>
#include <maps/libs/pgpool/include/pgpool3.h>
#include <maps/wikimap/mapspro/services/mrc/libs/common/include/suncalc.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/feature.h>
#include <maps/wikimap/mapspro/services/mrc/libs/fb/include/version.h>

#include <cstdint>
#include <string>

namespace maps::mrc::export_gen {

const std::string APP_NAME = "export_gen";
const std::string LAST_RUN_TIME = APP_NAME + ".timestamp";
const std::string LAST_TXN_ID = APP_NAME + ".txn_id";
const std::string ECSTATIC_MRC_DATASET_NAME = "yandex-maps-mrc";
const std::string ECSTATIC_FEATURES_SECRET_DATASET_NAME = "yandex-maps-mrc-features-secret";
const std::string ECSTATIC_ACTIVATION_NAME = "yandex-maps-mrc-activation";
constexpr int MAX_THREADS = 12;

enum struct Origin : int8_t { Db, Fb };

constexpr fb::TSchemaVersion CURRENT_FEATURE_SCHEMA_VERSION = 4;
constexpr fb::TSchemaVersion CURRENT_PHOTO_TO_EDGE_SCHEMA_VERSION = 1;
constexpr fb::TSchemaVersion CURRENT_GRAPH_SCHEMA_VERSION = 3;

struct Photo {
    geolib3::Point2 geodeticPos;          ///< 16 bytes
    std::string_view sourceId;            ///< 16 bytes
    geolib3::Direction2 direction;        ///< 8 bytes
    db::TId featureId;                    ///< 8 bytes
    chrono::TimePoint timestamp;          ///< 8 bytes
    db::CameraDeviation cameraDeviation;  ///< 2 bytes
    db::Dataset dataset;                  ///< 1 byte
    common::DayPart dayPart;              ///< 1 byte
    db::GraphType graph;                  ///< 1 byte
    Origin origin;                        ///< 1 byte
    db::FeaturePrivacy privacy;           ///< 1 byte
};

using Photos = std::vector<Photo>;
using PhotoRef = std::reference_wrapper<const Photo>;
using PhotoRefs = std::vector<PhotoRef>;

struct FeaturesSummary {
    Photos photos;
    db::TIds newToPublish;
    std::string fbVersion;
};

struct GraphDescriptor {
    std::string graphDir;
    db::GraphType graphType;
    std::string prevGraphDir;
    std::string prevPhotoToEdgeDir;
};

/// not thread-safe
Photo toPhoto(const db::Feature&, Origin = Origin::Db);

void markAsPublished(const db::TIds& featureIds, pgpool3::Pool&);

void updateMetadata(pgpool3::Pool&, db::TId txnId);

db::TId getLastFeatureTxnId(pgpool3::Pool&);

std::string format(size_t);

geolib3::Direction2 toDirection(const geolib3::Segment2& geoSegment);

}  // namespace maps::mrc::export_gen
