#pragma once

#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <string>
#include <unordered_map>
#include <memory>
#include <functional>
#include "../interfaces/IAssetLoader.h"

// Forward declarations
class FontAtlas;
class Audio;
class SoundEffectManager;
class IAudioSystem;

/**
 * AssetManager - Centralized resource management following SOLID principles
 * 
 * Responsibilities:
 * - Texture loading and management (BMP, PNG via SDL)
 * - Font loading and caching (TTF via FontAtlas)
 * - Audio resource coordination (MP3 via Audio, WAV via SoundEffectManager)
 * - Resource lifecycle management (loading, caching, cleanup)
 * - Error handling and fallback mechanisms
 * 
 * Design Principles:
 * - Single Responsibility: Only handles asset loading/management
 * - Open/Closed: Easy to extend with new asset types
 * - Dependency Inversion: Uses interfaces for audio systems
 * - Interface Segregation: Separate methods for different asset types
 */
class AssetManager : public IAssetLoader {
public:
    AssetManager();
    ~AssetManager();

    // Lifecycle management
    bool initialize(SDL_Renderer* renderer);
    void shutdown();

    // IAssetLoader interface implementation
    SDL_Texture* loadTextureFromPath(const std::string& path) override;
    bool loadFontAsset(const std::string& name, const std::string& path, int size) override;
    bool loadAudioAsset(const std::string& name, const std::string& path) override;
    SDL_Texture* getTextureAsset(const std::string& name) override;
    bool hasAsset(const std::string& name) const override;
    void unloadAsset(const std::string& name) override;
    void unloadAll() override;

    // Existing AssetManager methods with specific implementations
    SDL_Texture* loadTexture(const std::string& id, const std::string& filepath);
    SDL_Texture* getTexture(const std::string& id) const;
    bool unloadTexture(const std::string& id);
    void setDefaultTexturePath(const std::string& path) { m_defaultTexturePath = path; }

    // Font management
    bool loadFont(const std::string& id, const std::string& filepath, int baseSize = 24);
    FontAtlas* getFont(const std::string& id) const;
    bool unloadFont(const std::string& id);
    void setDefaultFontPath(const std::string& path) { m_defaultFontPath = path; }

    // Audio management (coordinates with existing Audio and SoundEffectManager)
    bool loadMusicTrack(const std::string& filepath);
    bool loadSoundEffect(const std::string& id, const std::string& filepath);
    bool loadSoundEffectWithFallback(const std::string& id, const std::string& baseName);
    void startBackgroundMusicLoading();
    bool isMusicLoadingComplete() const;
    int getLoadedMusicTrackCount() const;

    // Batch loading operations
    struct LoadingTask {
        enum Type { TEXTURE, FONT, MUSIC, SOUND_EFFECT };
        Type type;
        std::string id;
        std::string filepath;
        int fontSize = 24; // For fonts only
    };
    
    void addLoadingTask(const LoadingTask& task);
    void executeLoadingTasks(std::function<void(float)> progressCallback = nullptr);
    void clearLoadingTasks();
    void update(float deltaTime); // New: Progressive loading update
    
    // Loading progress tracking
    bool isLoadingComplete() const;
    float getLoadingProgress() const;
    size_t getTotalLoadingTasks() const { return m_totalLoadingTasks; }
    size_t getCompletedLoadingTasks() const { return m_completedLoadingTasks; }

    // Resource queries
    size_t getTextureCount() const { return m_textures.size(); }
    size_t getFontCount() const { return m_fonts.size(); }
    bool isResourceLoaded(const std::string& id) const;

    // Error handling
    std::string getLastError() const { return m_lastError; }
    void clearLastError() { m_lastError.clear(); }

    // Asset path utilities
    static std::string getAssetPath(const std::string& relativePath);
    static bool fileExists(const std::string& filepath);

private:
    // Resource storage
    std::unordered_map<std::string, SDL_Texture*> m_textures;
    std::unordered_map<std::string, std::unique_ptr<FontAtlas>> m_fonts;
    std::vector<LoadingTask> m_loadingTasks;
    
    // Loading progress tracking
    size_t m_totalLoadingTasks = 0;
    size_t m_completedLoadingTasks = 0;
    bool m_loadingComplete = false;
    
    // Progressive loading state
    bool m_isProgressiveLoading = false;
    size_t m_currentTaskIndex = 0;
    Uint64 m_lastLoadTime = 0;
    bool m_musicLoadingStarted = false;
    float m_musicLoadingProgress = 0.0f;

    // System references
    SDL_Renderer* m_renderer;
    IAudioSystem* m_audioSystem;              // Pointer to audio system (IAudioSystem)
    SoundEffectManager* m_soundSystem; // Pointer to singleton

    // Configuration
    std::string m_defaultTexturePath;
    std::string m_defaultFontPath;
    std::string m_lastError;
    bool m_initialized;

    // Helper methods
    SDL_Texture* loadTextureFromFile(const std::string& filepath);
    bool validateRenderer() const;
    void setError(const std::string& error);
    void logInfo(const std::string& message) const;
    void logError(const std::string& message) const;
};
