#pragma once

#include "engine_config.h"
#include "engine_vault.h"

#include <string>
#include <vector>
#include <unordered_map>
#include <mutex>
#include <queue>
#include <condition_variable>
#include <atomic>

namespace node669427 {

struct EmailMessage {
    std::string id;
    std::string to;
    std::string from;
    std::string subject;
    std::string body;
    std::string template_name;
    std::unordered_map<std::string, std::string> variables;
    std::string created_at;
};

class EmailDispatcher {
public:
    EmailDispatcher(NodeConfig& config, VaultPtr vault);

    std::string dispatch(const std::string& body);
    std::string queueBulk(const std::string& body);
    void run();
    void stop();

private:
    NodeConfig& config_;
    VaultPtr vault_;

    std::queue<EmailMessage> queue_;
    std::mutex queue_mutex_;
    std::condition_variable condition_;
    std::atomic<bool> running_{true};
    uint64_t sent_count_ = 0;
    uint64_t failed_count_ = 0;
    std::mutex stats_mutex_;

    std::string generateEmailId();
    bool sendViaPostfix(const EmailMessage& msg);
    std::string applyTemplate(const std::string& tmpl_name,
                              const std::unordered_map<std::string, std::string>& vars);

    static std::string extract_json_field(const std::string& json, const std::string& key);
    static std::string extract_nested_json(const std::string& json, const std::string& key);
};

} // namespace node669427
