#pragma once

#include <maps/wikimap/mapspro/services/mrc/libs/db/include/feature.h>
#include <maps/wikimap/mapspro/services/mrc/libs/config/include/config.h>
#include <maps/wikimap/mapspro/services/mrc/libs/sideview_classifier/include/sideview.h>

#include <boost/functional/hash.hpp>
#include <string>
#include <unordered_map>

namespace maps::mrc::sideview_classifier {

const TString COL_KEY_SOURCE_ID = "key_sid";
const TString COL_KEY_MIN_FEATURE_ID = "key_min_fid";
const TString COL_FEATURE_ID_1 = "fid1";
const TString COL_FEATURE_ID_2 = "fid2";
const TString COL_URL_1 = "url1";
const TString COL_URL_2 = "url2";
const TString COL_ORIENTATION_1 = "orient1";
const TString COL_ORIENTATION_2 = "orient2";
const TString COL_TYPE = "type";
const TString COL_CONFIDENCE = "confidence";

struct PassageKey
{
    std::string sourceId;
    db::TId minFeatureId;

    friend bool operator==(const PassageKey& lhs, const PassageKey& rhs)
    {
        return std::tie(lhs.sourceId, lhs.minFeatureId)
               == std::tie(rhs.sourceId, rhs.minFeatureId);
    }

    friend size_t hash_value(const PassageKey& key)
    {
        size_t result = 0;
        boost::hash_combine(result, key.sourceId);
        boost::hash_combine(result, key.minFeatureId);
        return result;
    }
};

struct Input
{
    PassageKey key;
    db::Feature feature1;
    db::Feature feature2;
};

struct Output
{
    PassageKey key;
    db::TId featureId;
    sideview::SideViewType type;
    float confidence;
};

using Inputs = std::vector<Input>;
using Outputs = std::vector<Output>;


using PassageKeyToFeaturesMap =
        std::unordered_map<PassageKey, db::Features, boost::hash<PassageKey>>;

using OutputsToFeaturesMap =
        std::unordered_map<PassageKey, Outputs, boost::hash<PassageKey>>;

} // maps::mrc::sideview_classifier
