#pragma once

#include "common.h"

#include <maps/libs/geolib/include/bounding_box.h>
#include <yandex/maps/mrc/toloka_client/assignment.h>
#include <yandex/maps/wiki/common/string_utils.h>

#include <maps/wikimap/mapspro/services/mrc/libs/toloka_manager/include/detection.h>

#include <iosfwd>
#include <ostream>
#include <string>
#include <unordered_map>
#include <vector>

namespace maps {
namespace mrc {
namespace toloka {

struct Detection {

// Input parameters of a single task of sign detection
using TaskInput = DetectionInput;

// Output parameters of a single task of sign detection
using TaskOutput = DetectionOutput;

// Result of a sign detection task
struct TaskResult {
    TaskInput input;
    TaskOutput output;
};

using TaskResults = std::vector<TaskResult>;

struct TaskSuite {
    std::string id;
    std::string poolId;
    size_t overlap;
    std::vector<TaskInput> tasks;
};

using TaskSuites = std::vector<TaskSuite>;
using IdToTaskSuite = std::unordered_map<std::string, TaskSuite>;

// Raw result of a task suite from a single user
struct AssignmentResult {
    std::string taskSuiteId;
    std::string assignmentId;
    io::AssignmentStatus status;
    std::string userId;
    std::vector<TaskInput> inputs;
    std::vector<TaskOutput> outputs;
};

using AssignmentResults = std::vector<AssignmentResult>;

// Map from task suite ID to collection of results from multiple users
using TaskSuiteIdToResults
    = std::unordered_map<std::string, AssignmentResults>;

struct TaskSuiteResult {
    TaskResults taskResults;
};

// Map from task suite ID to merged result
using TaskSuiteIdToResultMap
    = std::unordered_map<std::string, TaskSuiteResult>;

/**
 * Merge single task suite results received from multiple users
 */
static TaskSuiteResult mergeTaskSuiteResults(
    const AssignmentResults& assignmentResults);

/**
 * Evaluate and accept/reject user assignments
 */
static void evaluateAssignments(
    const io::TolokaClient& tolokaClient,
    const TaskSuiteResult& tsResult);

}; // struct Detection

} // toloka
} // mrc
} // maps
