// app_manager.h - App installation and management
// Milestone 10: Device-Side App Management
#pragma once

#include <string>
#include <vector>
#include <map>
#include <optional>
#include <functional>
#include <mutex>
#include <chrono>
#include <cstdint>

namespace mosis {

// Forward declarations
class LuaSandboxManager;

// Information about an installed app
struct InstalledApp {
    std::string package_id;
    std::string name;
    std::string version_name;
    int version_code = 0;
    std::string install_path;
    std::vector<std::string> permissions;
    std::chrono::system_clock::time_point installed_at;
    std::chrono::system_clock::time_point updated_at;
    int64_t package_size = 0;
    int64_t data_size = 0;
    bool is_system_app = false;
    std::string entry_point;
    std::string icon_path;
    std::string developer_name;
};

// Progress stages during installation
struct InstallProgress {
    enum class Stage {
        Downloading,
        Verifying,
        Extracting,
        Registering,
        Complete,
        Failed
    };

    Stage stage = Stage::Downloading;
    float progress = 0.0f;  // 0.0 - 1.0
    std::string error;

    static const char* StageName(Stage s) {
        switch (s) {
            case Stage::Downloading: return "downloading";
            case Stage::Verifying: return "verifying";
            case Stage::Extracting: return "extracting";
            case Stage::Registering: return "registering";
            case Stage::Complete: return "complete";
            case Stage::Failed: return "failed";
            default: return "unknown";
        }
    }
};

using ProgressCallback = std::function<void(const InstallProgress&)>;

// Manifest parsed from package
struct AppManifest {
    std::string id;
    std::string name;
    std::string version;
    int version_code = 0;
    std::string entry;
    std::string icon;
    std::string description;
    std::string developer_name;
    std::string developer_email;
    std::vector<std::string> permissions;
    int min_api_version = 1;
};

class AppManager {
public:
    explicit AppManager(const std::string& data_root);
    ~AppManager();

    // Prevent copying
    AppManager(const AppManager&) = delete;
    AppManager& operator=(const AppManager&) = delete;

    // Installation from URL
    bool Install(const std::string& package_url,
                 const std::string& signature,
                 ProgressCallback callback);

    // Installation from local file
    bool InstallFromFile(const std::string& package_path,
                         ProgressCallback callback);

    // Uninstallation
    bool Uninstall(const std::string& package_id, bool keep_data = false);

    // Updates
    bool Update(const std::string& package_id,
                const std::string& package_url,
                const std::string& signature,
                ProgressCallback callback);

    // Query installed apps
    std::vector<InstalledApp> GetInstalledApps() const;
    std::optional<InstalledApp> GetApp(const std::string& package_id) const;
    bool IsInstalled(const std::string& package_id) const;

    // Data management
    int64_t GetAppDataSize(const std::string& package_id) const;
    bool ClearAppData(const std::string& package_id);
    bool ClearAppCache(const std::string& package_id);
    bool BackupAppData(const std::string& package_id);
    bool RestoreAppData(const std::string& package_id);

    // App launching
    bool LaunchApp(const std::string& package_id);
    bool StopApp(const std::string& package_id);
    bool IsAppRunning(const std::string& package_id) const;

    // Integration with sandbox manager
    void SetSandboxManager(LuaSandboxManager* manager);

    // Get paths
    std::string GetDataRoot() const { return m_data_root; }
    std::string GetAppPath(const std::string& package_id) const;
    std::string GetAppDataPath(const std::string& package_id) const;
    std::string GetAppCachePath(const std::string& package_id) const;

    // System apps registration
    void RegisterSystemApp(const InstalledApp& app);

private:
    // Package verification
    bool VerifyPackage(const std::string& path);
    bool VerifySignature(const std::string& path, const std::string& signature);

    // Package operations
    std::optional<AppManifest> ExtractManifest(const std::string& package_path);
    bool ExtractPackage(const std::string& package_path, const std::string& dest_path);

    // Download helper
    bool DownloadFile(const std::string& url, const std::string& dest_path,
                      std::function<void(float)> progress_callback);

    // Registry persistence
    void LoadInstalledApps();
    void SaveInstalledApps();

    // Directory scanning for app discovery
    void ScanAppsDirectory();

    // Directory size calculation
    int64_t CalculateDirectorySize(const std::string& path) const;

    // Generate unique ID
    std::string GenerateUUID() const;

    std::string m_data_root;
    LuaSandboxManager* m_sandbox_manager = nullptr;
    mutable std::mutex m_mutex;
    std::map<std::string, InstalledApp> m_installed_apps;
};

} // namespace mosis
