#pragma once
#include "common.hpp"
#include "bridge.hpp"
#include <string>
#include <vector>
#include <map>
#include <json/json.h>
#include <curl/curl.h>
#include <atomic>
#include <thread>
#include <mutex>
#include <chrono>

struct XmrWallet {
    std::string address;
    uint64_t balance_atomic = 0;
    uint64_t unlocked_balance = 0;
    uint64_t height = 0;
};

struct XmrTx {
    std::string txid;
    uint64_t amount = 0;
    uint64_t confirmations = 0;
    uint64_t timestamp = 0;
    bool in = false;
    bool pending = false;
};

struct PaymentResult {
    bool success = false;
    std::string method;
    std::string txid;
    uint64_t amount = 0;
    std::string error;
    uint64_t confirmations = 0;
};

class XmrEngine {
public:
    XmrEngine(const std::string& rpc_url = "http://127.0.0.1:18082/json_rpc",
              const std::string& user = "wallet",
              const std::string& pass = "");
    ~XmrEngine();
    XmrWallet get_balance();
    std::string get_address();
    std::string transfer(const std::string& dest_addr, uint64_t amount_atomic, uint32_t priority = 1);
    std::vector<XmrTx> get_transfers(bool in = true, bool out = true, bool pending = true);
    uint64_t check_confirmations(const std::string& txid);
    PaymentResult verify_payment(const std::string& txid, uint64_t expected_amount, uint64_t min_confirms = 6);
private:
    std::string rpc_url_;
    std::string rpc_user_;
    std::string rpc_pass_;
    CURL* curl_;
    std::mutex curl_mtx_;
    Json::Value rpc_call(const std::string& method, const Json::Value& params);
};

class TronEngine {
public:
    explicit TronEngine(const std::string& signer_url = "http://127.0.0.1:9090");
    ~TronEngine();
    PaymentResult usdt_transfer(const std::string& to_addr, uint64_t amount_sun);
    uint64_t get_balance(const std::string& addr);
    Json::Value verify_tx(const std::string& txid);
private:
    std::string signer_url_;
    CURL* curl_;
    std::string http_post(const std::string& path, const std::string& body);
    std::string http_get(const std::string& path);
};

class StripeEngine {
public:
    StripeEngine(const std::string& api_key, const std::string& webhook_secret);
    ~StripeEngine();
    PaymentResult create_payment_intent(uint64_t amount_cents, const std::string& currency = "cad",
                                        const std::map<std::string, std::string>& metadata = {});
    PaymentResult confirm_payment(const std::string& payment_intent_id);
    PaymentResult refund(const std::string& payment_intent_id, uint64_t amount_cents = 0);
    bool verify_webhook(const std::string& payload, const std::string& sig_header);
private:
    std::string api_key_;
    std::string signing_secret_;
    CURL* curl_;
    std::mutex curl_mtx_;
    Json::Value stripe_request(const std::string& method, const std::string& path,
                                const std::string& body = "");
};

class EtransferEngine {
public:
    explicit EtransferEngine(const std::string& config_path);
    ~EtransferEngine();
    void start_polling();
    void stop_polling();
    std::vector<std::pair<std::string, double>> check_imap();
    bool verify_reference(const std::string& ref_code);
private:
    std::string imap_user_;
    std::string imap_pass_;
    std::atomic<bool> running_;
    std::thread poll_thread_;
    void poll_loop();
    std::string imap_cmd(const std::string& cmd);
};
