#ifndef NETWORKACCESSMANAGER_H
#define NETWORKACCESSMANAGER_H

#include <QFuture>
#include <QHttpMultiPart>
#include <QJsonDocument>
#include <QMutex>
#include <QMutexLocker>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QSharedPointer>
#include <memory>

class NetworkAccessManager : public QNetworkAccessManager
{
    Q_OBJECT

public:
    static NetworkAccessManager* instance();

protected:
    NetworkAccessManager(QObject* parent = nullptr);
    QNetworkReply* createRequest(Operation op,
                                 const QNetworkRequest& request,
                                 QIODevice* outgoingData = nullptr) override;
};

struct HttpResponse
{
    int code = 0;
    QJsonValue data;
    QString message;
    QByteArray rawData;
};

namespace TC {
class Interceptor
{
public:
    virtual ~Interceptor() = default;
    virtual void interceptRequest(QNetworkRequest& request) = 0;
    virtual void interceptResponse(QNetworkReply* reply) = 0;
};

struct RequestClientOptions
{
    QString baseURL;
    bool enableDefaultInterceptors = true;
    int timeout = 10000; // 默认超时时间为10秒
};

class RequestClient : public QObject
{
    Q_OBJECT
public:
    using Ptr = QSharedPointer<RequestClient>;

    explicit RequestClient(const RequestClientOptions& options = RequestClientOptions());
    ~RequestClient() {};

    // 禁用拷贝和赋值
    RequestClient(const RequestClient&) = delete;
    RequestClient& operator=(const RequestClient&) = delete;

    // 创建客户端实例
    static Ptr create(const QString& baseURL = "",
                      const RequestClientOptions& options = RequestClientOptions());

    // 获取全局实例
    static Ptr globalInstance();
    static Ptr baseGlobalInstance();

    // 拦截器管理
    void addInterceptor(std::shared_ptr<Interceptor> interceptor);
    void removeInterceptor(std::shared_ptr<Interceptor> interceptor);
    void clearInterceptors();

    // 基础URL设置
    void setBaseUrl(const QString& url) { m_baseUrl = url; }
    QString baseUrl() const { return m_baseUrl; }

    void setTimeout(int timeout) { m_timeout = timeout; }
    int timeout() const { return m_timeout; }

    // 同步请求
    HttpResponse get(const QString& url, const QVariantMap& params = {});
    HttpResponse post(const QString& url, const QJsonDocument& data = {});
    HttpResponse put(const QString& url, const QJsonDocument& data = {});
    HttpResponse deleteResource(const QString& url);
    HttpResponse upload(const QString& url, QHttpMultiPart* multiPart);

    // 异步请求
    QFuture<HttpResponse> getAsync(const QString& url, const QVariantMap& params = {});
    QFuture<HttpResponse> postAsync(const QString& url, const QJsonDocument& data = {});
    QFuture<HttpResponse> putAsync(const QString& url, const QJsonDocument& data = {});
    QFuture<HttpResponse> deleteAsync(const QString& url);
    QFuture<HttpResponse> uploadAsync(const QString& url, QHttpMultiPart* multiPart);

    // 文件下载
    bool download(const QString& url, const QString& saveFilePath);
    QFuture<bool> downloadAsync(const QString& url, const QString& saveFilePath);

signals:
    void requestStarted(const QUrl& url);
    void requestFinished(const QUrl& url, const HttpResponse& response);
    void requestFailed(const QUrl& url, const QString& error);

private:
    struct RequestContext
    {
        QNetworkReply* reply = nullptr;
        QByteArray responseData;
        bool handled = false;
    };

    // 内部实现方法
    QNetworkReply* sendGetRequest(const QString& url, const QVariantMap& params);
    QNetworkReply* sendPostRequest(const QString& url, const QJsonDocument& data);
    QNetworkReply* sendPutRequest(const QString& url, const QJsonDocument& data);
    QNetworkReply* sendDeleteRequest(const QString& url);
    QNetworkReply* sendUploadRequest(const QString& url, QHttpMultiPart* multiPart);

    void processRequest(QNetworkRequest& request);
    void processResponse(QNetworkReply* reply);
    HttpResponse parseReplyData(QNetworkReply* reply);

    QByteArray readReplyData(QNetworkReply* reply);
    void cacheReplyData(QNetworkReply* reply, const QByteArray& data);

    void setupDefaultInterceptors();

    QString m_baseUrl;
    int m_timeout = 10000;
    QSharedPointer<NetworkAccessManager> m_networkManager;
    QList<std::shared_ptr<Interceptor>> m_interceptors;
    QMutex m_interceptorMutex;
};

// 认证请求拦截器
class AuthRequestInterceptor : public Interceptor
{
public:
    void interceptRequest(QNetworkRequest& request) override;
    void interceptResponse(QNetworkReply* reply) override;
};

// 错误响应拦截器
class ErrorResponseInterceptor : public Interceptor
{
public:
    void interceptRequest(QNetworkRequest& request) override {}
    void interceptResponse(QNetworkReply* reply) override;
};
} // namespace TC

#endif // NETWORKACCESSMANAGER_H
