#pragma once

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

#include <maps/wikimap/mapspro/services/mrc/eye/lib/detection/include/store.h>
#include <maps/wikimap/mapspro/services/mrc/eye/lib/detection/include/match.h>

#include <vector>

namespace maps::mrc::eye {

// Находит все коллизии в детекциях у объектов.
// Под коллизией подразумевается тот факт, что
// одна и та же детекция принадлежит двух или более
// объектам.
//
//  Вход:
//    * objectsDetectionIds - набор множеств детекций для объектов
//  Выход:
//    * db::IdTo<std::vector<size_t>> - отображение detectionId
//      в массив индексов объектов, к которым они принадлежат
//
//  Пример:
//    Вход:
//      {{1, 2}, {1, 3}, {1, 2, 4}} - детекции для трех объектов
//    Выход:
//      {{1 : {0, 1, 2}}, {2 : {0, 2}}}
//      Т.е. detectionId = 1 принадлежит трем объектам,
//      а detectionId = 2 принадлежит двум объектам
db::IdTo<std::vector<size_t>> findCollisions(
    const std::vector<db::TIdSet>& objectsDetectionIds);

// Находит способ разрешить коллизии детекций в объектах.
// Коллизии разрешаются по двум критериям:
//   1) Основной критерий - confidence от матчера, характеризующий
//      уверенность в принадлежности детекции к другим детекциям объекта
//   2) Вспомогательный критерий - если с помощью матчера не удалось
//      найти confidence принадлежности ни к одному из объектов, то
//      считаем, что детекция принадлежит к объекту, у которого больше
//      всего других детекций.
//
// Выход:
//   * db::IdTo<size_t> - отображение detectionId в индекс выбранного объекта
db::IdTo<size_t> findCollisionSolutions(
    const DetectionStore& detectionStore,
    const FrameMatcher& frameMatcher,
    const DetectionMatcher& detectionMatcher,
    const std::vector<db::TIdSet>& objectsDetectionIds,
    const db::IdTo<std::vector<size_t>>& collisions);

// Применяет решения коллизий к набору множеств детекций для объектов
// В результате получается новый набор множеств, в котором уже нет коллизий.
//
//  Вход:
//    * objectsDetectionIds - набор множеств детекций объектов
//    * collisions - коллизии, которые есть в наборе множеств
//    * collisionSolutions - способ разрешить коллизии в наборе множеств
//  Выход:
//    * std::vector<db::TIdSet> - новый набор множеств без коллизий
//
//  Пример:
//    Вход:
//      objectsDetectionIds = {{1, 5, 6}, {1, 2, 3}, {1, 2, 4}}
//      collisions = {{1 : {0, 1, 2}}, {2: {1, 2}}}
//      collisionSolutions = {{1 : 0}, {2: 2}}
//    Выход:
//      {{1, 5, 6}, {3}, {2, 4}}
std::vector<db::TIdSet> applyCollisionSolutions(
    std::vector<db::TIdSet> objectsDetectionIds,
    const db::IdTo<std::vector<size_t>>& collisions,
    const db::IdTo<size_t>& collisionSolutions);

// Находит все коллизии в наборе множеств детекций у объектов,
// находит решение для этих коллизий и применяет к набору множеств,
// чтобы получить новый набор без коллизий.
std::vector<db::TIdSet> resolveCollisions(
    const DetectionStore& store,
    const FrameMatcher& frameMatcher,
    const DetectionMatcher& detectionMatcher,
    std::vector<db::TIdSet> objectsDetectionIds);

} // namespace maps::mrc::eye
