#pragma once

#include <maps/libs/common/include/retry.h>
#include <yandex/maps/wiki/revision/common.h>

#include <maps/libs/enum_io/include/enum_io_fwd.h>
#include <maps/libs/pgpool/include/pgpool3.h>
#include <maps/libs/log8/include/log8.h>
#include <maps/libs/locale/include/codes.h>
#include <maps/libs/locale/include/locale.h>

#include <maps/wikimap/mapspro/libs/sender/include/localized_string.h>

#include <chrono>
#include <map>
#include <optional>
#include <thread>
#include <pqxx/pqxx>

namespace maps::wiki::releases_notification {

using Email = std::string;
using Hstore = std::string;

enum class ReleaseType
{
    Sat,
    Vec,
    Event,
    News,
    Survey
};

DECLARE_ENUM_IO(ReleaseType);


enum class Mode
{
    Real, // Full workflow, available only in production

    Dry,  // Use fake sender and write messages only to log instead of real emails

    Test  // Send emails only to predefined list,
          // even if there aren't any users with that email to notify
};

DECLARE_ENUM_IO(Mode);


class TaskParams
{
public:
    TaskParams(pqxx::transaction_base& txnCore, revision::DBID dbTaskId);

    // for test purposes only
    TaskParams(
        std::string blogUrl,
        Mode mode,
        ReleaseType releaseType,
        revision::DBID dbTaskId,
        std::vector<Email> testEmails);

    const std::string& blogUrl() const { return blogUrl_; }
    Mode mode() const { return mode_; }
    ReleaseType releaseType() const { return releaseType_; }
    revision::DBID dbTaskId() const { return dbTaskId_; }
    const std::vector<Email>& testEmails() const { return testEmails_; }

private:
    std::string blogUrl_;
    Mode mode_;
    ReleaseType releaseType_;
    revision::DBID dbTaskId_;
    std::vector<Email> testEmails_;
};

struct UserInfo
{
    revision::UserID uid;
    std::string email;
    locale::Locale locale;
    std::optional<std::string> username;
};

const std::string DEFAULT_LANG = "ru";
const locale::Locale DEFAULT_LOCALE(locale::Lang::Ru);

maps::common::RetryPolicy defaultRetryPolicy();

struct PgPools
{
    pgpool3::Pool& longReadPool;
    pgpool3::Pool& socialPool;
};

using LocaleStringMap = std::map<locale::Locale, std::string>;

std::string getBestLocalizedString(
    const sender::LocalizedString& localizedString,
    const locale::Locale& locale);

} // namespace maps::wiki::releases_notification

