#pragma once

#include "../core/Config.hpp"
#include <filesystem>
#include <functional>
#include <string>

namespace GModTeach {
namespace Extractor {

using ProgressCallback = std::function<void(float progress, const std::string& status)>;

struct PipelineStats {
    size_t totalBinsFound = 0;
    size_t totalGmasFound = 0;
    size_t binsProcessed = 0;
    size_t gmasProcessed = 0;
    size_t errors = 0;
};

class GmadExtractor {
public:
    static bool ExtractWith7Zip(
        const std::filesystem::path& archive,
        const std::filesystem::path& outDir,
        const std::filesystem::path& custom7zExe = {}
    );

    static bool ProcessGmaFile(
        const std::filesystem::path& gmaPath,
        const std::filesystem::path& gmadExe,
        const std::filesystem::path& gmodDir
    );

    static bool ProcessBinFile(
        const std::filesystem::path& binPath,
        const std::filesystem::path& gmadExe,
        const std::filesystem::path& gmodDir,
        const std::filesystem::path& custom7zExe = {}
    );

    static bool ProcessExtractedFolder(
        const std::filesystem::path& extractedDir,
        const std::filesystem::path& gmodDir
    );

    static PipelineStats RunInstallationPipeline(
        const Core::AppConfig& config,
        bool cleanAfterwards = false,
        ProgressCallback progressCb = nullptr
    );

    static bool CleanSourceDirectory(const std::filesystem::path& sourceDir);

private:
    static bool MoveItem(const std::filesystem::path& src, const std::filesystem::path& dst);
    static bool MoveDirectoryContents(
        const std::filesystem::path& srcDir,
        const std::filesystem::path& dstDir,
        const std::string& skipName = ""
    );
};

} 
} 
