#ifndef IMAPCONNECTION_H
#define IMAPCONNECTION_H

#include <QSslSocket>
#include <QObject>
#include <functional>
#include <QMap>
#include <QByteArray>

class ImapConnection : public QObject
{
    Q_OBJECT
public:
    explicit ImapConnection(QObject *parent = nullptr);
    ~ImapConnection();

    void connectToHost(const QString &host, int port, bool useSsl);
    void login(const QString &username, const QString &password,
               bool useAuthPlain,
               std::function<void(bool, const QString&)> callback);
    void sendCommand(const QString &command,
                    std::function<void(bool, const QString&)> callback);
    void disconnect();
    
    // Synchronous version: blocks until response or timeout
    bool sendCommandWait(const QString &command, QString &response, int msecs);
    bool sendCommandWaitBytes(const QString &command, QByteArray &response, int msecs);

signals:
    void connected();
    void disconnected();
    void errorOccurred(const QString &message);
    void untaggedResponse(const QString &line); // for * RESPONSES
    void ready(); // connection ready for authentication (TCP connected for plain, encrypted for SSL)

private slots:
    void onConnected();
    void onEncrypted();
    void onReadyRead();
    void onSocketError(QAbstractSocket::SocketError error);

private:
    QSslSocket *m_socket;
    QString m_host;
    int m_port;
    bool m_useSsl;
    QString m_username;
    QString m_password;
    int m_tagCounter;
    QString m_responseBuffer;
    QMap<QString, std::function<void(bool, const QString&)>> m_pendingCallbacks; // keyed by tag
    QMetaObject::Connection m_readyReadConnection;

    void processLine(const QString &line);
    QString generateTag();
public:
    void sendRaw(const QString &data);
};

#endif // IMAPCONNECTION_H
