#pragma once

#include <SDL3/SDL.h>
#include <string>
#include <vector>
#include <mutex>
#include <atomic>
#include <unordered_map>
#include "../resources/ResourceManager.h"

// Lightweight AssetLoader scaffold.
// Responsibilities:
// - Queue textures to load (main thread) and perform incremental loads via performStep().
// - Store loaded SDL_Texture* instances and provide accessors.
// - Collect loading errors thread-safely.
// NOTE: All SDL texture creation MUST happen on the thread that owns the SDL_Renderer.
class AssetLoader {
public:
    AssetLoader();
    ~AssetLoader();

    void init(SDL_Renderer* renderer);
    void shutdown();

    void setBasePath(const std::string& basePath);
    void setResourceManager(resources::ResourceManager* mgr);

    // Queue a texture path (relative to base path) for loading.
    void queueTexture(const std::string& path);

    // Perform a single loading step (load one queued asset).
    // Returns true when all queued tasks are complete, false otherwise.
    bool performStep();

    // Progress in [0,1]. If no tasks, returns 1.0f.
    float getProgress() const;

    // Retrieve and clear accumulated error messages.
    std::vector<std::string> getAndClearErrors();

    // Get a loaded texture (or nullptr if not loaded).
    SDL_Texture* getTexture(const std::string& path) const;

    // Adopt an externally-created texture so AssetLoader owns its lifetime.
    // If a texture is already registered for this path, it will be replaced.
    void adoptTexture(const std::string& path, SDL_Texture* texture);

    // Return currently-loading path (empty when idle).
    std::string getCurrentLoading() const;

private:
    SDL_Renderer* m_renderer = nullptr;
    std::string m_basePath;
    resources::ResourceManager* m_resourceManager = nullptr;

    // queued paths (simple FIFO)
    std::vector<std::string> m_queue;
    mutable std::mutex m_queueMutex;

    std::unordered_map<std::string, SDL_Texture*> m_textures;
    mutable std::mutex m_texturesMutex;

    std::vector<std::string> m_errors;
    mutable std::mutex m_errorsMutex;

    std::atomic<int> m_totalTasks{0};
    std::atomic<int> m_loadedTasks{0};

    std::string m_currentLoading;
    mutable std::mutex m_currentLoadingMutex;
};
