#pragma once
#include <memory>
#include <typeindex>
#include <typeinfo>
#include <imgui.h>
#include "entity.h"

/**
 * namespace for the Entity-Component-System (ECS)
 */
namespace ecs {
    class Entity;

// Classe de base pour tous les composants
class Component {
public:
    Component() = default;
    virtual ~Component() = default;

    // Empêcher la copie
    Component(const Component&) = delete;
    Component& operator=(const Component&) = delete;

    // Permettre le déplacement
    Component(Component&&) = default;
    Component& operator=(Component&&) = default;

    /**
     * Virtual function to initialize the component.
     */
    virtual void Initialize() {}

    /**
     * Virtual function to update the component.
     * @param deltaTime Time since the last update.
     * @param entity The entity this component is attached to.
     */
    virtual void Update(float deltaTime) {}

    /**
     * Serialize the component to a string (for debugging or saving).
     * @return A string representation of the component.
     */
    virtual std::string Serialize() const { return ""; }

    /**
     * Deserialize the component from a string (for loading).
     * @param data The string data to deserialize from.
     * @return True if deserialization was successful, otherwise false.
     */
    virtual bool Deserialize(const std::string& data) { return false;}

    /**
     * Virtual function to render ImGui controls for the component.
     * This can be overridden by derived components to provide custom UI.
     */
    virtual void OnImGuiRender() { /* Default implementation does nothing */ }

    /**
     * Set the parent entity of this component.
     * @param parent A shared pointer to the parent entity.
     */
    void SetParent(std::shared_ptr<Entity> parent) { m_parent = parent; }

    /**
     * Get the parent entity of this component.
     * @return A shared pointer to the parent entity, or nullptr if it has been destroyed.
     */
    std::shared_ptr<Entity> GetParent() const { return m_parent.lock(); }

private:
    std::weak_ptr<Entity> m_parent;
    
};

/**
 * Type alias for a shared pointer to a Component.
 */
using ComponentPtr = std::shared_ptr<Component>;
    
/**
* Type alias for a unique identifier for a component type.
*/
using ComponentTypeID = std::type_index;

/**
 * Function to get the unique type ID for a component type.
 */
template<typename T>
ComponentTypeID GetComponentTypeID() {
    static_assert(std::is_base_of<Component, T>::value, "T must derive from Component");
    return std::type_index(typeid(T));
}

}  // namespace ecs
