#pragma once

#include <unordered_map>
#include <string>
#include <memory>
#include <typeindex>
#include <mutex>
#include <queue>
#include <filesystem>
#include <thread>
#include <atomic>
#include "Asset.h"

namespace OX {

    class AssetManager {
    public:
        static void Init(const std::string& projectDir);
        static void Shutdown();
        static void Tick(); // Call once per frame

        static void RegisterAssetMetadata(const std::string& id, const std::string& type, const std::string& path);
        static bool LoadAsset(const std::string& id);

        template<typename T>
        static std::shared_ptr<T> Get(const std::string& id) {
            if (s_AssetMap.find(id) == s_AssetMap.end())
                LoadAsset(id);

            auto it = s_AssetMap.find(id);
            if (it == s_AssetMap.end()) return nullptr;
            if (s_AssetTypes[id] != std::type_index(typeid(T))) return nullptr;

            return std::static_pointer_cast<T>(it->second);
        }

    private:
        struct AssetMetadata {
            std::string type;
            std::string path;
        };

        static void ScanAssetsRecursive(const std::filesystem::path& root);
        static std::string DetectTypeFromExtension(const std::filesystem::path& path);
        static std::string GetVirtualPath(const std::filesystem::path& absolute);

        static std::unordered_map<std::string, std::shared_ptr<Asset>> s_AssetMap;
        static std::unordered_map<std::string, std::type_index> s_AssetTypes;
        static std::unordered_map<std::string, AssetMetadata> s_AssetDatabase;

        static std::mutex s_QueueMutex;
        static std::queue<std::pair<std::string, AssetMetadata>> s_LoadQueue;

        static std::thread s_BackgroundThread;
        static std::atomic<bool> s_Running;

        static std::filesystem::path s_ProjectDirectory;
    };

} // namespace OX
