#pragma once

#include <maps/wikimap/mapspro/services/mrc/libs/db/include/eye/recognition.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/txn_id.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/table_traits.h>

namespace maps::mrc::db {
namespace eye {
namespace table {

using namespace sql_chemistry;

struct Recognition: Table<db::eye::Recognition> {
    static constexpr std::string_view name_{"eye.recognition"sv};

    static constexpr BigSerialKey id{"recognition_id"sv, name_};
    static constexpr NumericColumn<TId> txnId{"txn_id"sv, name_};
    static constexpr NumericColumn<TId> frameId{"frame_id"sv, name_};
    static constexpr Int16Column orientation{"orientation", name_};
    static constexpr EnumColumn<RecognitionType> type{"type", name_};
    static constexpr EnumColumn<RecognitionSource> source{"source", name_};
    static constexpr NumericColumn<int16_t> version{"version", name_};
    static constexpr Nullable<JsonColumn> value{"value"sv, name_};

    static constexpr auto columns_()
    {
        return std::tie(id, txnId, frameId, orientation, type, source, version, value);
    }
};

struct DetectionGroup: Table<db::eye::DetectionGroup> {
    static constexpr std::string_view name_{"eye.detection_group"sv};

    static constexpr BigSerialKey id{"group_id"sv, name_};
    static constexpr NumericColumn<TId> txnId{"txn_id"sv, name_};
    static constexpr NumericColumn<TId> frameId{"frame_id"sv, name_};
    static constexpr EnumColumn<DetectionType> type{"type"sv, name_};
    static constexpr BooleanColumn approved{"approved"sv, name_};

    static constexpr auto columns_()
    {
        return std::tie(id, txnId, frameId, type, approved);
    }
};

struct Detection: Table<db::eye::Detection> {
    static constexpr std::string_view name_{"eye.detection"sv};

    static constexpr BigSerialKey id{"detection_id"sv, name_};
    static constexpr NumericColumn<TId> txnId{"txn_id"sv, name_};
    static constexpr NumericColumn<TId> groupId{"group_id"sv, name_};
    static constexpr BooleanColumn deleted{"deleted"sv, name_};
    static constexpr JsonColumn attrs{"attrs"sv, name_};

    static constexpr auto columns_()
    {
        return std::tie(id, txnId, groupId, deleted, attrs);
    }
};

struct RecognitionTask: Table<db::eye::RecognitionTask> {
    static constexpr std::string_view name_{"eye.recognition_task"sv};

    static constexpr BigSerialKey id{"recognition_task_id"sv, name_};
    static constexpr NullableNumericColumn<TId> parentId{"parent_id"sv, name_};
    static constexpr NumericColumn<TId> recognitionId{"recognition_id"sv, name_};
    static constexpr NumericColumn<TId> taskId{"task_id"sv, name_};
    static constexpr NumericColumn<TId> txnId{"txn_id"sv, name_};

    static constexpr auto columns_()
    {
        return std::tie(id, parentId, recognitionId, taskId, txnId);
    }
};

struct DetectionRelation: Table<db::eye::DetectionRelation> {
    static constexpr std::string_view name_{"eye.detection_relation"sv};

    static constexpr BigSerialKey id{"relation_id"sv, name_};
    static constexpr NumericColumn<TId> masterDetectionId{"master_detection_id"sv, name_};
    static constexpr NumericColumn<TId> slaveDetectionId{"slave_detection_id"sv, name_};
    static constexpr NumericColumn<TId> txnId{"txn_id"sv, name_};
    static constexpr BooleanColumn deleted{"deleted"sv, name_};

    static constexpr auto columns_()
    {
        return std::tie(id, masterDetectionId, slaveDetectionId, txnId, deleted);
    }
};

} // namespace table

using RecognitionGateway = db::TxnIdGatewayBase<table::Recognition>;
using DetectionGroupGateway = db::TxnIdGatewayBase<table::DetectionGroup>;
using DetectionGateway = db::TxnIdGatewayBase<table::Detection>;
using RecognitionTaskGateway = db::TxnIdGatewayBase<table::RecognitionTask>;
using DetectionRelationGateway = db::TxnIdGatewayBase<table::DetectionRelation>;

} // namespace eye

TABLE_TRAITS(eye::Recognition, eye::table::Recognition);
TABLE_TRAITS(eye::DetectionGroup, eye::table::DetectionGroup);
TABLE_TRAITS(eye::Detection, eye::table::Detection);
TABLE_TRAITS(eye::RecognitionTask, eye::table::RecognitionTask);
TABLE_TRAITS(eye::DetectionRelation, eye::table::DetectionRelation);

} // namespace maps::mrc::db::eye
