#include <maps/libs/log8/include/log8.h>
#include <maps/libs/common/include/exception.h>
#include <maps/libs/cmdline/include/cmdline.h>

#include <maps/libs/json/include/value.h>

#include <maps/wikimap/mapspro/services/autocart/pipeline/libs/config/include/config.h>

#include <string>
#include <iomanip>
#include <fstream>
#include <sstream>

using namespace maps::wiki::autocart::pipeline;

namespace {

size_t getBuildingsCount(const std::string& bldsJsonPath) {
    return maps::json::Value::fromFile(bldsJsonPath).size();
}

std::string createTolokersValidationComment(size_t bldsCount, const TolokersConfig& config) {
    static const size_t MIN_OVERLAP = 2;
    static const size_t MAX_OVERLAP = 3;

    size_t suitesCount = std::ceil(static_cast<double>(bldsCount) / config.realTasksCount());
    double minBudget = suitesCount * config.rewardPerAssignment() * MIN_OVERLAP;
    double maxBudget = suitesCount * config.rewardPerAssignment() * MAX_OVERLAP;
    INFO() << suitesCount;
    std::stringstream ss;
    ss << std::fixed << std::setprecision(2);
    ss << "Переведите тикет **!!(зел)в работу!!**, чтобы запустить валидацию толокерами, ";
    ss << " или **!!закройте!!** его, чтобы отменить дальнейшее выполнение процесса.\n";
    ss << "Параметры валидации:\n";
    ss << "* Количество зданий: " << bldsCount << "\n";
    ss << "* Количество заданий на одной странице в Я.Толоке: " << config.realTasksCount() << "\n";
    ss << "* Цена за одну страницу: $" << config.rewardPerAssignment() << "\n";
    ss << "* Минимальное перекрытие для одного задания: " << MIN_OVERLAP << "\n";
    ss << "* Максимальное перекрытие для одного задания: " << MAX_OVERLAP << "\n";
    ss << "* Предполагаемый бюджет валидации в Я.Толоке: $" << minBudget << " - $" << maxBudget;

    return ss.str();
}

} // namespace

int main(int argc, const char** argv)
try {
    maps::cmdline::Parser parser("Create tolokers validation comment");

    maps::cmdline::Option<std::string> bldsJsonPath = parser.string("blds")
        .required()
        .help("Path to json file with buildings");

    maps::cmdline::Option<std::string> tolokersConfigPath = parser.string("tolokers_config")
        .required()
        .help("Path to tolokers config file");

    maps::cmdline::Option<std::string> outputPath = parser.string("output")
        .required()
        .help("Path to output text file with comment");

    parser.parse(argc, const_cast<char**>(argv));


    INFO() << "Loading tolokers config: " << tolokersConfigPath;
    TolokersConfig tolokersConfig(tolokersConfigPath);

    INFO() << "Loadinf buildings from file: " << bldsJsonPath;
    size_t bldsCount = getBuildingsCount(bldsJsonPath);

    INFO() << "Creating Startrek comment text";
    std::string comment = createTolokersValidationComment(bldsCount, tolokersConfig);

    INFO() << "Saving comment into file: " << outputPath;
    std::ofstream ofs(outputPath);
    REQUIRE(ofs.is_open(), "Failed to open file: " + outputPath);
    ofs << comment;
    ofs.close();

    return EXIT_SUCCESS;
}
catch (const maps::Exception& e) {
    INFO() << e;
    return EXIT_FAILURE;
}
catch (const std::exception& e) {
    INFO() << e.what();
    return EXIT_FAILURE;
}
catch (...) {
    INFO() << "Caught unknown exception";
    return EXIT_FAILURE;
}
