#include <maps/wikimap/mapspro/libs/notifications/include/mail_event.h>

#include <maps/libs/enum_io/include/enum_io.h>
#include <maps/libs/log8/include/log8.h>

#include <aws/sqs/model/SendMessageRequest.h>

namespace maps::json {

void json(const wiki::notifications::MailEvent& event, json::ObjectBuilder builder)
{
    builder["puid"] = event.puid;
    builder["mail-type"] = toString(event.type);
    builder["args"] = event.args;
}

} // namespace maps::json

namespace maps::wiki::notifications {

namespace {

using namespace std::string_view_literals;

constexpr enum_io::Representations<MailType> MAIL_TYPE_STRINGS {
    {MailType::NewsSubscriptionThanks, "news-subscription-welcome-mail"sv}, // TODO: rename to news-subscription-thanks
    {MailType::AchievementEditsCount, "achievement-edits-count"sv}
};

template<typename Object>
std::string toJsonString(const Object& obj)
{
    json::Builder builder;
    builder << obj;
    return builder.str();
}

} // anon namespace

DEFINE_ENUM_IO(MailType, MAIL_TYPE_STRINGS);


MailEvent::MailEvent(uint64_t puid, MailType type, json::Value args) :
    puid(puid), type(type), args(std::move(args))
{
}


MailEventSender::MailEventSender(
    std::string sqsQueueName,
    const sqs::Configuration& sqsConfig,
    const Aws::SQS::SQSClient& sqsClient)
        : sqsQueueName_(std::move(sqsQueueName))
        , sqsConfig_(sqsConfig)
        , sqsClient_(sqsClient)
{
}

bool MailEventSender::send(const MailEvent& event) const
{
    const auto eventSerialized = toJsonString(event);

    Aws::SQS::Model::SendMessageRequest sendRequest;
    sendRequest.SetQueueUrl(sqsConfig_.getQueueUrl(sqsQueueName_));
    sendRequest.SetMessageBody(eventSerialized);

    INFO() << "Sending message " << eventSerialized << " to queue " << sqsQueueName_;
    auto sendResult = sqsClient_.SendMessage(sendRequest);

    if (sendResult.IsSuccess()) {
        return true;
    }

    ERROR() << "Error sending message " << eventSerialized
            << " to queue " << sqsQueueName_ << ". "
            << sendResult.GetError().GetMessage();
    return false;
}

} // namespace maps::wiki::notifications
