#pragma once

#include "base_component.h"
#include <map>
#include <string>
#include <functional>

namespace gencpp {
namespace registry {

class ComponentRegistry {
public:
    using ComponentCreator = std::function<std::unique_ptr<core::BaseComponent<void*>>()>;

    static ComponentRegistry& Instance();

    void Register(const std::string& type, ComponentCreator creator);
    std::unique_ptr<core::BaseComponent<void*>> Create(const std::string& type);

    class Iterator {
    public:
        using MapIterator = std::map<std::string, ComponentCreator>::iterator;
        
        Iterator(MapIterator it) : m_it(it) {}
        
        bool operator!=(const Iterator& other) const { return m_it != other.m_it; }
        void operator++() { ++m_it; }
        const std::string& GetType() const { return m_it->first; }

    private:
        MapIterator m_it;
    };

    Iterator Begin() { return Iterator(m_creators.begin()); }
    Iterator End() { return Iterator(m_creators.end()); }

private:
    ComponentRegistry() = default;
    std::map<std::string, ComponentCreator> m_creators;
};

} // namespace registry
} // namespace gencpp
