#pragma once

#include <types/base/types.h>
#include <types/ptr/ref_counted.h>
#include <types/ptr/intrusive_ptr.h>
#include <types/const/priority.h>
#include <string>
#include <vector>
#include <tbb/concurrent_hash_map.h>

namespace extra2d {

/**
 * @brief 服务状态枚举
 */
enum class SvcState : uint8 {
    None,
    Inited,
    Running,
    Paused,
    Shutdown
};

/**
 * @brief 服务基类
 * 
 * 所有子系统服务都继承此类，提供统一的生命周期管理
 */
class IService : public RefCounted {
public:
    virtual ~IService() = default;

    virtual bool init() { return true; }
    virtual void shutdown() {}
    virtual void pause() {}
    virtual void resume() {}

    virtual void update(float dt) {}
    virtual void lateUpdate(float dt) {}
    virtual void fixedUpdate(float dt) {}

    virtual const char* name() const = 0;
    virtual int pri() const { return Pri::Default; }

    SvcState state() const { return state_; }
    bool isInited() const { return state_ >= SvcState::Inited; }
    bool isEnabled() const { return enabled_; }
    void setEnabled(bool v) { enabled_ = v; }

protected:
    IService() = default;
    SvcState state_ = SvcState::None;
    bool enabled_ = true;

    friend class SvcMgr;
};

/**
 * @brief 服务管理器
 * 
 * 管理所有服务的注册、初始化、更新和关闭
 */
class SvcMgr {
public:
    static SvcMgr& inst();

    void reg(IService* svc);
    void unreg(const char* name);
    Ptr<IService> get(const char* name);

    template<typename T>
    Ptr<T> getAs(const char* name) {
        return static_cast<T*>(get(name).get());
    }

    bool initAll();
    void pauseAll();
    void resumeAll();
    void shutdownAll();

    void updateAll(float dt);
    void lateUpdateAll(float dt);
    void fixedUpdateAll(float dt);

    bool has(const char* name) const;
    size_t count() const;

private:
    SvcMgr() = default;

    using SvcMap = tbb::concurrent_hash_map<std::string, Ptr<IService>>;
    SvcMap svcMap_;
    std::vector<Ptr<IService>> sortedSvcs_;

    void sortSvcs();
};

#define SVC_MGR extra2d::SvcMgr::inst()

} // namespace extra2d
