#ifndef HTTPREQUESTMANAGER_H
#define HTTPREQUESTMANAGER_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTimer>
#include <QMap>
#include <QUrl>
#include <QJsonDocument>

class HttpRequestManager : public QObject
{
    Q_OBJECT

public:
    explicit HttpRequestManager(QObject* parent = nullptr);
    ~HttpRequestManager();

    void registerEndpoint(const QString& dataKey, const QUrl& url, const QByteArray& method = "GET",
                          const QByteArray& body = QByteArray(), const QMap<QByteArray, QByteArray>& headers = {});

    void requestData(const QString& dataKey);
    void cancleRequest(const QString& dataKey);

    void setDefaultTimeout(int ms);
    void setRetryPolicy(int maxRetries, int retryInterval);

    bool hasVaildEndpoint(const QString& dataKey);

signals:
    void dataReceived(const QString& dataKey, const QVariant& data);
    void requestFailed(const QString& dataKey, const QString& error);
    //void requestProgress(const QString& dataKey, int progress);

private slots:
    void onReplyFinished();
    void onReplyError(QNetworkReply::NetworkError code);

private:
    struct EndpointConfig
    {
        QString dataKey;
        QUrl url;
        QByteArray method; //"GET","POST",使用QByteArray而非QString是因为网络编程中的参数都是QByteArray,直接使用可以避免QString引起的转码开销
        QByteArray body; //JSON格式的请求体内容,如"{\"key\":\"value\"}"
        QMap<QByteArray, QByteArray> headers; //http请求头，如{{"Content-Type", "application/json"}, {"Authorization", "Bearer token123"}}
        QNetworkReply* activeReply = nullptr;
        QTimer* timeoutTimer = nullptr;
        int retryCount = 0; //当前重试次数
        int maxRetries = 0; //最大重试次数
        int retryInterval = 1000;
    };

    QNetworkAccessManager m_networkManager;
    QMap<QString, EndpointConfig> m_endpoints;
    int m_defaultTimeout = 5000;
    int m_maxRetries = 2;
    int m_retryIntrval = 1000;

    void sendRequest(EndpointConfig& config);
    void handleResponse(const QString& dataKey, QNetworkReply* reply);
    void handleRequestTimeout(const QString& dataKey);
    void scheduleRetry(const QString& dataKey);

    void parseJsonResponse(const QString& dataKey, const QByteArray& data);
    void parseTextResponse(const QString& dataKey, const QByteArray& data);
    void parseBinaryResponse(const QString& dataKey, const QByteArray& data);
};

#endif
