#ifndef FILETRANSFER_H
#define FILETRANSFER_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QFile>
#include <QDir>
#include <QFileInfo>
#include <QJsonDocument>
#include <QJsonObject>
#include <QHttpMultiPart>

class FileTransfer : public QObject {
    Q_OBJECT
    Q_PROPERTY(double downloadProgress READ downloadProgress NOTIFY downloadProgressChanged)
    Q_PROPERTY(double uploadProgress READ uploadProgress NOTIFY uploadProgressChanged)

public:
    static FileTransfer* instance() {
        static FileTransfer _instance;
        return &_instance;
    }

    Q_INVOKABLE void postDownload(const QString& url,
                                  const QString& savePath,
                                  const QVariantMap& postData,
                                  const QString& additionalobj) {
        if (m_currentDownload) {
            emit downloadCompleted(false, u8"已有进行中的下载");
            return;
        }

        // 获取文件所在的目录路径
        QFileInfo fileInfo(savePath);
        QString dirPath = fileInfo.absolutePath();

        // 检查目录是否存在，如果不存在则创建
        QDir dir;
        if (!dir.exists(dirPath)) {
            if (!dir.mkpath(dirPath)) {
                emit downloadCompleted(false, u8"无法创建目录");
                cleanup();
                return;
            }
        }

        // 创建目标文件
        m_downloadFile = new QFile(savePath, this);
        if (!m_downloadFile->open(QIODevice::WriteOnly)) {
            emit downloadCompleted(false, u8"无法创建文件");
            cleanup();
            return;
        }

        QUrl u(url);
        // 配置 HTTPS
        QNetworkRequest request(u);
        QSslConfiguration sslConfig = request.sslConfiguration();
        sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone); // 跳过证书验证
        request.setSslConfiguration(sslConfig);

        // 构建 POST 数据（JSON 格式示例）
        QJsonDocument jsonDoc(QJsonObject::fromVariantMap (postData));
        QByteArray postBody = jsonDoc.toJson();

        // 发送请求
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
        m_currentDownload = manager.post(request, postBody);

        // 连接信号
        connect(m_currentDownload, &QNetworkReply::readyRead, [this](){
            m_downloadFile->write(m_currentDownload->readAll());
        });

        connect(m_currentDownload, &QNetworkReply::downloadProgress,
                [this,additionalobj](qint64 bytesReceived, qint64 bytesTotal){
                    m_downloadProgress = bytesTotal > 0
                                             ? bytesReceived / (double)bytesTotal
                                             : 0;
                    emit downloadProgressChanged(m_downloadProgress,additionalobj);
                });

        connect(m_currentDownload, &QNetworkReply::finished, [this,additionalobj](){
            if (m_downloadFile) {
                m_downloadFile->flush();
                m_downloadFile->close();
            }

            QVariant statusCodeVariant = m_currentDownload->attribute(QNetworkRequest::HttpStatusCodeAttribute);
            if (statusCodeVariant.isValid()) {
                int statusCode = statusCodeVariant.toInt();
                qDebug() << "HTTP Status Code:" << statusCode;
            }

            bool success = !m_currentDownload->error();
            QString message = success ? additionalobj : m_currentDownload->errorString();

            if (success) {
                // 验证文件完整性
                QFileInfo fi(m_downloadFile->fileName());
                qint64 expectedSize = m_currentDownload->header(
                                                           QNetworkRequest::ContentLengthHeader).toLongLong();
                if (fi.size() != expectedSize && expectedSize > 0) {
                    success = false;
                    message = "文件不完整";
                }
            }
            cleanup();
            emit downloadCompleted(success, message.toUtf8());

        });
    }

    Q_INVOKABLE void postUpload(const QString& url,
                                const QString& filePath,
                                const QString& remotePath,
                                const QString& additionalobj) {
        if (m_currentDownload) { // 复用同一个网络管理器，保持单请求
            emit uploadCompleted(false, u8"已有进行中的传输");
            return;
        }

        // 准备要上传的文件
        QFile *uploadFile = new QFile(filePath, this);
        if (!uploadFile->open(QIODevice::ReadOnly)) {
            emit uploadCompleted(false, u8"无法打开文件");
            uploadFile->deleteLater();
            return;
        }

        // 创建多部分数据
        QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType, this);

        // 添加文件部分
        QHttpPart filePart;
        filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
        filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
                           QVariant(QString("form-data; name=\"file\"; filename=\"%1\"")
                                        .arg(remotePath + QFileInfo(filePath).fileName())));
        filePart.setBodyDevice(uploadFile);
        uploadFile->setParent(multiPart); // 文件对象由multiPart管理生命周期
        multiPart->append(filePart);

        QUrl u(url);
        QNetworkRequest request(u);

        // 配置HTTPS
        QSslConfiguration sslConfig = request.sslConfiguration();
        sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
        request.setSslConfiguration(sslConfig);

        // 发送请求
        m_currentDownload = manager.post(request, multiPart);
        multiPart->setParent(m_currentDownload); // 由reply管理multiPart生命周期

        // 连接进度信号
        connect(m_currentDownload, &QNetworkReply::uploadProgress,
                [this, additionalobj](qint64 bytesSent, qint64 bytesTotal){
                    m_uploadProgress = bytesTotal > 0
                                           ? bytesSent / (double)bytesTotal
                                           : 1;
                    emit uploadProgressChanged(m_uploadProgress, additionalobj); // 带附加参数
                });

        // 处理完成信号
        connect(m_currentDownload, &QNetworkReply::finished, [this, additionalobj](){
            bool success = (m_currentDownload->error() == QNetworkReply::NoError);
            QString message = success ? u8"上传成功" : m_currentDownload->errorString();
            cleanup();
            emit uploadCompleted(success, additionalobj);
        });
    }

    double downloadProgress() const { return m_downloadProgress; }
    double uploadProgress() const { return m_uploadProgress; }

signals:
    // 下载相关信号
    void downloadProgressChanged(double progress,const QString& additional);
    void downloadCompleted(bool success, const QString& message);

    // 上传相关信号（原有）
    void uploadProgressChanged(double progress ,const QString& additional);
    void uploadCompleted(bool success, const QString& message);

private:
    explicit FileTransfer(QObject* parent = nullptr)
        : QObject(parent), m_downloadProgress(0), m_uploadProgress(0),
        m_currentDownload(nullptr), m_downloadFile(nullptr) {}

    QNetworkAccessManager manager;
    double m_downloadProgress;
    double m_uploadProgress;
    QNetworkReply* m_currentDownload;
    QFile* m_downloadFile;

    void cleanup() {
        if (m_downloadFile) {
            m_downloadFile->deleteLater();
            m_downloadFile = nullptr;
        }
        if (m_currentDownload) {
            m_currentDownload->deleteLater();
            m_currentDownload = nullptr;
        }
        m_downloadProgress = 0;
    }
};
#endif // FILETRANSFER_H
