#include <maps/wikimap/ugc/backoffice/src/lib/assignments/load.h>
#include <maps/wikimap/ugc/libs/common/constants.h>
#include <maps/wikimap/mapspro/libs/query_builder/include/select_query.h>
#include <maps/infra/yacare/include/error.h>

namespace maps::wiki::ugc::backoffice {

namespace qb = maps::wiki::query_builder;

namespace {

proto::assignment::Status parseAssignmentStatus(const std::string& status)
{
    switch (maps::enum_io::fromString<AssignmentStatus>(status)) {
        case AssignmentStatus::Active:
            return proto::assignment::ACTIVE;
        case AssignmentStatus::Done:
            return proto::assignment::DONE;
        case AssignmentStatus::Skipped:
            return proto::assignment::SKIPPED;
        case AssignmentStatus::Expired:
            return proto::assignment::EXPIRED;
    }
}

} // namespace

pqxx::result loadAssignmentStatus(
    pqxx::transaction_base& txn,
    Uid uid,
    const AssignmentId& assignmentId)
{
    const auto whereConditions = qb::WhereConditions()
        .appendQuoted(columns::TASK_ID, assignmentId.value())
        .append(columns::UID, std::to_string(uid.value()));
    return qb::SelectQuery(tables::ASSIGNMENT, {columns::STATUS}, whereConditions).exec(txn);
}

proto::backoffice::AssignmentStatus getAssignmentStatus(
    pqxx::transaction_base& txn,
    Uid uid,
    const AssignmentId& assignmentId)
{
    auto rows = loadAssignmentStatus(txn, uid, assignmentId);
    if (rows.empty()) {
        throw yacare::errors::NotFound()
            << "Not found assignment for uid=" << uid << " and task_id=" << assignmentId;
    }
    REQUIRE(
        rows.size() == 1,
        "Found more than 1 assignment for uid=" << uid << " and task_id=" << assignmentId
    );
    proto::backoffice::AssignmentStatus status;
    status.set_status(parseAssignmentStatus(rows[0][0].as<std::string>()));
    return status;
}

} // namespace maps::wiki::ugc::backoffice
