#pragma once

#include <maps/wikimap/mapspro/services/mrc/eye/lib/detect_panel/include/config.h>

#include <maps/wikimap/mapspro/services/mrc/eye/lib/common/include/load.h>

#include <maps/wikimap/mapspro/services/mrc/libs/common/include/exif.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/eye/frame.h>
#include <maps/wikimap/mapspro/services/mrc/libs/yt/include/common.h>
#include <maps/wikimap/mapspro/services/mrc/libs/yt/include/config.h>

#include <tuple>

namespace maps::mrc::eye {

struct PartedFrame {
    PartedFrame(): partId(), frame(sql_chemistry::GatewayAccess<db::eye::Frame>::construct()) {}

    PartedFrame(
            db::TId partId,
            const db::eye::Frame& frame)
        : partId(partId)
        , frame(frame)
    {}

    template<class T>
    static auto introspect(T& t)
    {
        return std::tie(t.partId, t.frame);
    }

    static constexpr auto columns() { return std::make_tuple("part_id", "frame"); }

    db::TId partId;
    db::eye::Frame frame;
};

struct Partitions {
    std::vector<PartedFrame> frames;
    size_t partitionNumber;
};

Partitions makePartitions(
        const std::vector<db::eye::Frames>& sequences,
        size_t size,
        size_t margin);

struct DetectedPanel {
    DetectedPanel(): frame(sql_chemistry::GatewayAccess<db::eye::Frame>::construct()), restBox() {}

    DetectedPanel(
            const db::eye::Frame& frame,
            const common::ImageBox& restBox)
        : frame(frame)
        , restBox(restBox)
    {}

    template<class T>
    static auto introspect(T& t) { return std::tie(t.frame, t.restBox); }

    static constexpr auto columns() { return std::make_tuple("frame", "rest_box"); }

    db::eye::Frame frame;
    common::ImageBox restBox;
};

using DetectedPanels = std::vector<DetectedPanel>;

DetectedPanels detectPanel(const DetectPanelConfig& config, const Partitions& partitions);

} // namespace maps::mrc::eye
