#ifndef GENAI_NLP_SERVICE_PROXY_H
#define GENAI_NLP_SERVICE_PROXY_H

#include <functional>
#include <unordered_map>

#include "_chatmodelconfig.h"
#include "chat.h"
#include "genainlpserver.h"

namespace kyai::genai::nlp {

using ReconnectedCallback = std::function<void()>;

class GenAiNlpServiceProxy {
public:
    ~GenAiNlpServiceProxy();

    bool connectToServer();
    bool reconnectServer();

    int initEngine(const char *config, int *sessionId);

    void destroyEngine(int sessionId);

    void setChatResultCallback(const ChatResultCallback &callback,
                               void *userData);

    void setReconnectedCallback(const ReconnectedCallback &callback);

    void setChatModelConfig(int sessionId, const ChatModelConfig &config);

    void chat(int sessionId, const std::string &question);

    void stopChat(int sessionId);

    void clearChatMessage(int sessionId);

    void setChatSystemPromptId(int sessionId, PromptId promptId);

    void addSystemMessage(int sessionId, const std::string &message);

    void chatWithHistoryMessages(int sessionId, const std::string &messages);

private:
    void connectChatResultSignals(int sessionId);

    static void onChatResultCallback(GDBusConnection *connection,
                                     const gchar *senderName,
                                     const gchar *objectPath,
                                     const gchar *interfaceName,
                                     const gchar *signalName,
                                     GVariant *parameters, gpointer userData);
    static void onChatFinishedCallback(GObject *sourceObject, GAsyncResult *res,
                                       gpointer userData);

    void handleErrorOccurred(int errorCode);
    void handleServerClosed();
    void handleChatTimeout();
    void handleGeneralError();
    void handleMessagesEmptyError();

    void startCallbackTimer();
    void removeCallbackTimerIfExists();
    void resetCallbackTimer();
    void handleCallbackTimeout();

private:
    ChatResultCallback chatResultCallback_{nullptr};
    ReconnectedCallback reconnectedCallback_{nullptr};
    void *userData_{nullptr};

    AiRuntimeGenAiNlpService *proxy_{nullptr};
    GenAiNlpServer *genNlpServer_{nullptr};
    int currentSessionId_{0};
    guint subscriptionId_{0};
    guint timeoutId_{0};
    int reconnectAttempts_{0};
    static constexpr int maxReconnectAttempts = 10;
};

}  // namespace kyai::genai::nlp
#endif  // GENAI_NLP_SERVICE_PROXY_H
