#pragma once

#include <QCryptographicHash>
#include <QObject>
#include <QString>
#include <QUrl>

#include <memory>

class QNetworkAccessManager;
class QNetworkReply;
class QSaveFile;
class QTimer;

// Загрузка одного архива сезонной сборки в файл. Пишем потоком и сверяем
// sha256: пак — это сотни мегабайт, держать их в памяти незачем, а
// распаковывать битую загрузку поверх рабочей .minecraft нельзя.
//
// Распаковкой занимается BuildSwitcher: она идёт в отдельном потоке вместе с
// остальными операциями над содержимым .minecraft.
//
// Набор геттеров повторяет VersionInstaller и JavaInstaller: панель загрузки в
// интерфейсе читает их одинаково, независимо от того, кто сейчас работает.
class SeasonalPackDownloader : public QObject
{
    Q_OBJECT

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

    bool isRunning() const { return m_running; }
    QString label() const { return m_label; }
    QString stage() const { return m_stage; }
    QString currentFile() const { return m_currentFile; }

    qint64 bytesDone() const { return m_bytesDone; }
    qint64 bytesTotal() const { return m_bytesTotal; }
    double fraction() const;   // 0..1, либо -1 пока итог неизвестен

    // targetPath перезаписывается: недокачанный пак с прошлой попытки не
    // должен пережить новую.
    void download(const QUrl &url,
                  const QString &targetPath,
                  const QString &sha256,
                  qint64 expectedSize,
                  const QString &label);
    void cancel();

signals:
    void started(const QString &label);
    void progressChanged();
    void finished(const QString &path);
    void failed(const QString &label, const QString &message);
    void canceled(const QString &label);

private:
    void fail(const QString &message);
    void reset();
    void scheduleProgress();
    void flushProgress();

    QNetworkAccessManager *m_network;
    QNetworkReply *m_reply = nullptr;
    std::unique_ptr<QSaveFile> m_file;
    QCryptographicHash m_hash{QCryptographicHash::Sha256};

    QString m_targetPath;
    QString m_sha256;
    QString m_label;
    QString m_stage;
    QString m_currentFile;

    qint64 m_bytesDone = 0;
    qint64 m_bytesTotal = 0;

    QTimer *m_progressTimer;
    bool m_progressDirty = false;
    bool m_running = false;
    bool m_canceling = false;
};
