#pragma once

#include "Global/Global_Type.h"
#include <optional>
#include <stdexcept>

class ObjectVars
{
private:
    // 底层存储：key -> 数组（始终是vector，即使只有一个元素）
    ObjectVarsMap _data;

public:
    ObjectVars() = default;
    ~ObjectVars() = default;

    // 禁止拷贝（按需开启）
    ObjectVars(const ObjectVars &) = delete;
    ObjectVars &operator=(const ObjectVars &) = delete;

    // 允许移动
    ObjectVars(ObjectVars &&) = default;
    ObjectVars &operator=(ObjectVars &&) = default;

    // 1. 向key对应的数组添加元素（核心接口，无论添加几个元素都用这个）
    template <typename T>
    void Add(const std::string &key, const T &value)
    {
        static_assert(std::is_constructible_v<ObjectVarsType, T>, "不支持的类型（未在ObjectVarsType中定义）");
        _data[key].push_back(ObjectVarsType{value}); // 直接追加到数组，保证始终是数组形式
    }

    // 2. 批量添加元素（一次添加多个值到数组）
    template <typename T>
    void AddAll(const std::string &key, const std::vector<T> &values)
    {
        static_assert(std::is_constructible_v<ObjectVarsType, T>, "不支持的类型（未在ObjectVarsType中定义）");
        for (const auto &val : values)
        {
            _data[key].push_back(ObjectVarsType{val});
        }
    }

    // 3. 替换key对应的整个数组（覆盖原有所有元素）
    template <typename T>
    void SetArray(const std::string &key, const std::vector<T> &values)
    {
        static_assert(std::is_constructible_v<ObjectVarsType, T>, "不支持的类型（未在ObjectVarsType中定义）");
        // 先清空原有数据，再添加新数组
        _data[key].clear();
        AddAll(key, values);
    }

    // 4. 获取key对应的整个数组（返回指定类型的vector，类型不匹配的元素会被过滤）
    template <typename T>
    std::vector<T> GetArray(const std::string &key) const
    {
        std::vector<T> result;
        auto it = _data.find(key);
        if (it == _data.end())
        {
            return result; // key不存在，返回空数组
        }
        // 只提取类型匹配的元素
        for (const auto &var : it->second)
        {
            if (const auto *val = std::get_if<T>(&var))
            {
                result.push_back(*val);
            }
        }
        return result;
    }

    // 5. 获取数组中指定索引的元素（返回optional，索引越界或类型不匹配则返回nullopt）
    template <typename T>
    std::optional<T> GetAt(const std::string &key, size_t index) const
    {
        auto it = _data.find(key);
        if (it == _data.end() || index >= it->second.size())
        {
            return std::nullopt; // key不存在或索引越界
        }
        // 检查类型是否匹配
        if (const auto *val = std::get_if<T>(&it->second[index]))
        {
            return *val;
        }
        return std::nullopt; // 类型不匹配
    }

    // 6. 检查key是否存在（无论数组是否为空）
    bool Has(const std::string &key) const
    {
        return _data.find(key) != _data.end();
    }

    // 7. 获取数组长度（key不存在则返回0）
    size_t GetSize(const std::string &key) const
    {
        auto it = _data.find(key);
        return (it != _data.end()) ? it->second.size() : 0;
    }

    // 8. 清空key对应的数组（保留key但数组为空）
    void ClearArray(const std::string &key)
    {
        auto it = _data.find(key);
        if (it != _data.end())
        {
            it->second.clear();
        }
    }

    // 9. 删除整个key（包括数组）
    void Remove(const std::string &key)
    {
        _data.erase(key);
    }

    // 10. 清空所有数据
    void ClearAll()
    {
        _data.clear();
    }
};