#pragma once

#include <maps/wikimap/mapspro/services/autocart/pipeline/libs/toloka/include/states.h>
#include <maps/wikimap/mapspro/services/mrc/libs/toloka_client/include/yandex/maps/mrc/toloka_client/client.h>

#include <set>
#include <string>
#include <unordered_map>

namespace maps::wiki::autocart::pipeline {

struct AssessorTask {
    explicit AssessorTask(const mrc::toloka::io::TaskSuiteItem& task);
    AssessorTask(const std::string& mapURL, const std::string& bldURL);

    // URL to satellite image
    std::string mapURL;
    // URL to satellite image with building contour
    std::string bldURL;
};

struct AssessorAnswer {
    explicit AssessorAnswer(const mrc::toloka::io::AssignmentSolution& solution);
    AssessorAnswer(const TolokaState& state, int height, int ftTypeId);

    TolokaState state;
    int height;
    int ftTypeId;
};


struct HeightRange {
    HeightRange() = default;
    HeightRange(int minHeight, int maxHeight);
    // cond format:
    //   <min_height>-<max_height>
    HeightRange(const std::string& cond);

    int min;
    int max;
};

struct FTTypeList {
    FTTypeList() = default;
    FTTypeList(const std::set<int>& ftTypeIds);
    // cond format:
    //  <ft_type_id1>,<ft_type_id2>
    FTTypeList(const std::string& cond);

    std::set<int> ids;
};

struct AssessorGoldenAnswer {
    explicit AssessorGoldenAnswer(const mrc::toloka::io::KnownSolutions& solutions);
    AssessorGoldenAnswer(
        const TolokaState& state,
        const HeightRange& heightRange,
        const FTTypeList& ftTypeList);

    TolokaState state;
    HeightRange heightRange;
    FTTypeList ftTypeList;
};

struct AssessorTaskSolution {
    AssessorTask task;
    AssessorAnswer answer;
    std::optional<AssessorGoldenAnswer> golden;
};

bool operator==(const AssessorAnswer& real, const AssessorGoldenAnswer& golden);


struct AssessorStatistics {
    // count golden and real tasks
    size_t completedTasksCount = 0;
    // percentage of correct answers to golden tasks
    double quality = 1.;
};

// Calculate statistics for each user
// in time range [startTimePoint, endTimePoint]
std::unordered_map<std::string, AssessorStatistics>
getAssessorIdToStatistics(
    const mrc::toloka::io::TolokaClient& client,
    const std::string& projectId,
    const chrono::TimePoint& startTimePoint,
    const chrono::TimePoint& endTimePoint);

// Load all completed tasks by user id
// in time range [startTimePoint, endTimePoint]
std::vector<AssessorTaskSolution>
getAssessorSolutions(
    const mrc::toloka::io::TolokaClient& client,
    const std::string& assessorId,
    const std::string& projectId,
    const chrono::TimePoint& startTimePoint,
    const chrono::TimePoint& endTimePoint);

} // namespace maps::wiki::autocart::pipeline
