#include <maps/wikimap/mapspro/services/mrc/long_tasks/toloka_manager_cron_jobs/lib/include/approvement.h>

namespace maps {
namespace mrc {
namespace toloka {

Approvement::TaskOutput Approvement::mergeSingleTaskResults(
    const Approvement::AssignmentResults& results,
    size_t taskIdx,
    Approvement::UserIdToStat& userIdToStat)
{
    std::vector<Approvement::TaskOutput> outputs;
    for (const auto& res : results) {
        outputs.push_back(res.outputs[taskIdx]);
    }

    std::sort(outputs.begin(), outputs.end());
    const auto pair = longestEqualRange(outputs.begin(), outputs.end());
    if ((size_t)std::distance(pair.first, pair.second) <= outputs.size()
                                                              / 2) {
        return Approvement::TaskOutput{Approvement::TaskAnswer::No};
    }
    Approvement::TaskOutput majorityOutput = *pair.first;

    for (const auto& res : results) {
        if (!userIdToStat.count(res.userId)) {
            userIdToStat.emplace(res.userId, Approvement::UserStat(res));
        }
        auto& stat = userIdToStat.at(res.userId);
        const auto& userOutput = res.outputs[taskIdx];
        if (userOutput == majorityOutput) {
            ++stat.correctCount;
        }
    }
    return majorityOutput;
}

Approvement::TaskSuiteResult Approvement::mergeTaskSuiteResults(
    const Approvement::AssignmentResults& assignmentResults)
{
    return mergeTaskSuiteResultsImpl<Approvement>(assignmentResults);
}

void Approvement::evaluateAssignments(
    const io::TolokaClient& tolokaClient,
    const Approvement::TaskSuiteResult& tsResult)
{
    evaluateAssignmentsImpl<Approvement>(tolokaClient, tsResult);
}

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