#pragma once

#include <memory>
#include <string>
#include <unordered_map>
#include <typeindex>
#include <type_traits>
#include <vector>

#include <glog/logging.h>

#include "map_layer.h"

namespace Map2 {

class MapManager {
public:
    MapManager() = default;

    // 注册一个MapLayer（如PointCloudMapLayer、SCMapLayer等）
    template<typename T, typename... Args>
    std::shared_ptr<T> CreateOrGetLayer(Args&&... args) {
        static_assert(std::is_base_of<MapLayer, T>::value, "T must inherit from MapLayer");
        std::type_index idx(typeid(T));
        auto it = layers_.find(idx);
        if (it != layers_.end()) {
            return std::dynamic_pointer_cast<T>(it->second);
        }
        auto layer = std::make_shared<T>(std::forward<Args>(args)...);
        layers_[idx] = layer;
        return layer;
    }

    // 获取指定类型的MapLayer
    template<typename T>
    std::shared_ptr<T> GetLayer() const {
        static_assert(std::is_base_of<MapLayer, T>::value, "T must inherit from MapLayer");
        std::type_index idx(typeid(T));
        auto it = layers_.find(idx);
        if (it != layers_.end()) {
            return std::dynamic_pointer_cast<T>(it->second);
        }
        return nullptr;
    }

    // 保存所有MapLayer到指定目录
    bool SaveAll(const std::string& dir) const {
        bool ok = true;

        for (auto& kv : layers_) {
            // 这里假设每个MapLayer有Clear方法，否则可重置为新对象
            // kv.second->Clear();
            // 若无Clear接口，可重置为新对象
            ok &= kv.second->saveFromFolder(dir);
        }

        return ok;
    }

    // 加载所有已注册类型的MapLayer（需先CreateOrGetLayer）
    bool LoadAll(const std::string& dir) {

        bool ok = true;

        for (auto& kv : layers_) {
            // 这里假设每个MapLayer有Clear方法，否则可重置为新对象
            // kv.second->Clear();
            // 若无Clear接口，可重置为新对象
            ok &= kv.second->loadFromFolder(dir);
            LOG(INFO) << "finish load map: " << kv.second->getTypeName();
        }

        return ok;
    }

    // 清空所有地图
    void Clear() {
        for (auto& kv : layers_) {
            // 这里假设每个MapLayer有Clear方法，否则可重置为新对象
            // kv.second->Clear();
            // 若无Clear接口，可重置为新对象
            kv.second.reset();
        }
        layers_.clear();
    }

    // 获取所有已注册的MapLayer
    std::vector<std::shared_ptr<MapLayer>> GetAllLayers() const {
        std::vector<std::shared_ptr<MapLayer>> result;
        for (const auto& kv : layers_) {
            result.push_back(kv.second);
        }
        return result;
    }

private:
    std::unordered_map<std::type_index, std::shared_ptr<MapLayer>> layers_;
};

} // namespace Map