/**************************************************************************/
/*  asset_downloader.h                                                    */
/**************************************************************************/
/*                         This file is part of:                          */
/*                          AETHEX ENGINE                                 */
/*                     https://aethex.foundation                          */
/**************************************************************************/
/* Copyright (c) 2026-present AeThex Labs.                                */
/**************************************************************************/

#ifndef AETHEX_ASSET_DOWNLOADER_H
#define AETHEX_ASSET_DOWNLOADER_H

#include "marketplace_client.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/object/ref_counted.h"
#include "scene/main/http_request.h"

class AeThexAssetDownloader : public RefCounted {
	GDCLASS(AeThexAssetDownloader, RefCounted);

public:
	enum InstallLocation {
		INSTALL_PROJECT,       // Install to current project
		INSTALL_USER_DATA,     // Install to user data folder
		INSTALL_GLOBAL_ADDONS  // Install to global addons
	};

	struct DownloadJob {
		String asset_id;
		String download_url;
		String destination_path;
		int64_t total_bytes = 0;
		int64_t downloaded_bytes = 0;
		bool is_active = false;
		bool is_complete = false;
		bool has_error = false;
		String error_message;
	};

private:
	Vector<DownloadJob> download_queue;
	DownloadJob current_download;
	HTTPRequest *http_request = nullptr;
	String base_download_path;
	InstallLocation default_location = INSTALL_PROJECT;
	
	void _process_queue();
	void _on_download_completed(int p_result, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_body);
	String _get_install_path(InstallLocation location, const String &asset_id, const String &asset_name) const;

protected:
	static void _bind_methods();

public:
	// Configuration
	void set_default_location(InstallLocation location) { default_location = location; }
	InstallLocation get_default_location() const { return default_location; }
	
	void set_base_download_path(const String &path) { base_download_path = path; }
	String get_base_download_path() const { return base_download_path; }
	
	// Download management
	void queue_download(const Ref<AeThexAsset> &asset, InstallLocation location = INSTALL_PROJECT);
	void queue_download_url(const String &asset_id, const String &url, const String &destination);
	void start_downloads();
	void cancel_download(const String &asset_id);
	void cancel_all_downloads();
	void pause_downloads();
	void resume_downloads();
	
	// Status
	bool is_downloading() const { return current_download.is_active; }
	int get_queue_size() const { return download_queue.size(); }
	float get_current_progress() const;
	String get_current_asset_id() const { return current_download.asset_id; }
	
	// Installation
	Error install_asset(const String &zip_path, const String &destination);
	Error uninstall_asset(const String &asset_id, const String &installed_path);
	PackedStringArray get_installed_files(const String &asset_id) const;
	
	// Verification
	bool verify_download(const String &file_path, const String &expected_hash);
	String calculate_file_hash(const String &file_path) const;
	
	// Signals
	// download_started(asset_id: String)
	// download_progress(asset_id: String, progress: float, bytes_downloaded: int, total_bytes: int)
	// download_completed(asset_id: String, path: String)
	// download_failed(asset_id: String, error: String)
	// install_completed(asset_id: String, installed_path: String)
	// queue_empty()
	
	AeThexAssetDownloader();
	~AeThexAssetDownloader();
};

VARIANT_ENUM_CAST(AeThexAssetDownloader::InstallLocation);

#endif // AETHEX_ASSET_DOWNLOADER_H
