#include <glaze/glaze.hpp>
#include <variant>
#include <map>
#include <vector>
#include <string>
#include <cstdint>
#include <optional>
#include <type_traits>

using integer = std::int32_t;
using uinteger = std::uint32_t;
using decimal = double;
using boolean = bool;
using string = std::string;

// 前向声明
struct LSPAny;
using LSPObject = std::map<string, LSPAny>;
using LSPArray = std::vector<LSPAny>;

using LSPAnyVariant = std::variant<
    LSPObject,
    LSPArray,
    string,
    decimal, // 放在前面，优先匹配数字
    boolean,
    std::nullptr_t
>;

struct LSPAny {
    LSPAnyVariant value;
    
    // 默认构造函数
    LSPAny() : value(nullptr) {}
    
    // 拷贝和移动构造函数
    LSPAny(const LSPAny& other) : value(other.value) {}
    LSPAny(LSPAny&& other) noexcept : value(std::move(other.value)) {}
    
    // 针对每种支持的类型的构造函数
    LSPAny(const std::map<string, LSPAny>& val) : value(val) {}
    LSPAny(std::map<string, LSPAny>&& val) : value(std::move(val)) {}
    
    LSPAny(const std::vector<LSPAny>& val) : value(val) {}
    LSPAny(std::vector<LSPAny>&& val) : value(std::move(val)) {}
    
    LSPAny(const string& val) : value(val) {}
    LSPAny(string&& val) : value(std::move(val)) {}
    LSPAny(const char* val) : value(string(val)) {}
    
    // 所有数字类型都转换为 decimal
    LSPAny(int val) : value(static_cast<decimal>(val)) {}
    LSPAny(long val) : value(static_cast<decimal>(val)) {}
    LSPAny(long long val) : value(static_cast<decimal>(val)) {}
    LSPAny(unsigned int val) : value(static_cast<decimal>(val)) {}
    LSPAny(unsigned long val) : value(static_cast<decimal>(val)) {}
    LSPAny(unsigned long long val) : value(static_cast<decimal>(val)) {}
    LSPAny(float val) : value(static_cast<decimal>(val)) {}
    LSPAny(double val) : value(val) {}
    LSPAny(long double val) : value(static_cast<decimal>(val)) {}
    
    LSPAny(boolean val) : value(val) {}
    LSPAny(std::nullptr_t) : value(nullptr) {}

    // 赋值操作符
    LSPAny& operator=(const LSPAny& other) {
        value = other.value;
        return *this;
    }
    
    LSPAny& operator=(LSPAny&& other) noexcept {
        value = std::move(other.value);
        return *this;
    }
    
    // 针对每种支持的类型的赋值操作符
    LSPAny& operator=(const std::map<string, LSPAny>& val) {
        value = val;
        return *this;
    }
    
    LSPAny& operator=(std::map<string, LSPAny>&& val) {
        value = std::move(val);
        return *this;
    }
    
    LSPAny& operator=(const std::vector<LSPAny>& val) {
        value = val;
        return *this;
    }
    
    LSPAny& operator=(std::vector<LSPAny>&& val) {
        value = std::move(val);
        return *this;
    }
    
    LSPAny& operator=(const string& val) {
        value = val;
        return *this;
    }
    
    LSPAny& operator=(string&& val) {
        value = std::move(val);
        return *this;
    }
    
    LSPAny& operator=(const char* val) {
        value = string(val);
        return *this;
    }
    
    // 所有数字类型都转换为 decimal
    LSPAny& operator=(int val) {
        value = static_cast<decimal>(val);
        return *this;
    }
    
    LSPAny& operator=(long val) {
        value = static_cast<decimal>(val);
        return *this;
    }
    
    LSPAny& operator=(long long val) {
        value = static_cast<decimal>(val);
        return *this;
    }
    
    LSPAny& operator=(unsigned int val) {
        value = static_cast<decimal>(val);
        return *this;
    }
    
    LSPAny& operator=(unsigned long val) {
        value = static_cast<decimal>(val);
        return *this;
    }
    
    LSPAny& operator=(unsigned long long val) {
        value = static_cast<decimal>(val);
        return *this;
    }
    
    LSPAny& operator=(float val) {
        value = static_cast<decimal>(val);
        return *this;
    }
    
    LSPAny& operator=(double val) {
        value = val;
        return *this;
    }
    
    LSPAny& operator=(long double val) {
        value = static_cast<decimal>(val);
        return *this;
    }
    
    LSPAny& operator=(boolean val) {
        value = val;
        return *this;
    }
    
    LSPAny& operator=(std::nullptr_t) {
        value = nullptr;
        return *this;
    }
    
    // 类型检查辅助函数
    template<typename T>
    bool is() const { return std::holds_alternative<T>(value); }
    
    template<typename T>
    T& get() { return std::get<T>(value); }
    
    template<typename T>
    const T& get() const { return std::get<T>(value); }
    
    // 访问操作符
    template<typename Visitor>
    auto visit(Visitor&& visitor) const {
        return std::visit(std::forward<Visitor>(visitor), value);
    }
    
    template<typename Visitor>
    auto visit(Visitor&& visitor) {
        return std::visit(std::forward<Visitor>(visitor), value);
    }
};

// glaze 自动支持 std::variant，无需额外配置
namespace glz {
    template <>
    struct meta<LSPAny> {
        using T = LSPAny;
        static constexpr auto value = &T::value;
    };
}

// ===== 简单清晰的转换模板 =====

// 转换工具类
struct LSPConvert {
    // === 基本类型的转换（优先级最高） ===
    
    // boolean
    static LSPAny ToLSPAny(boolean value) {
        return LSPAny(value);
    }
    
    // 整数类型
    static LSPAny ToLSPAny(int value) {
        return LSPAny(value);
    }
    
    static LSPAny ToLSPAny(long value) {
        return LSPAny(value);
    }
    
    static LSPAny ToLSPAny(long long value) {
        return LSPAny(value);
    }
    
    static LSPAny ToLSPAny(unsigned int value) {
        return LSPAny(value);
    }
    
    static LSPAny ToLSPAny(unsigned long value) {
        return LSPAny(value);
    }
    
    static LSPAny ToLSPAny(unsigned long long value) {
        return LSPAny(value);
    }
    
    // 浮点类型
    static LSPAny ToLSPAny(float value) {
        return LSPAny(value);
    }
    
    static LSPAny ToLSPAny(double value) {
        return LSPAny(value);
    }
    
    static LSPAny ToLSPAny(long double value) {
        return LSPAny(value);
    }
    
    // string
    static LSPAny ToLSPAny(const string& str) {
        return LSPAny(str);
    }
    
    static LSPAny ToLSPAny(const char* str) {
        return LSPAny(str);
    }
    
    // nullptr
    static LSPAny ToLSPAny(std::nullptr_t) {
        return LSPAny(nullptr);
    }
    
    // LSPAny 自身
    static LSPAny ToLSPAny(const LSPAny& any) {
        return any;
    }
    
    // === 容器类型的转换 ===
    
    // vector
    template<typename T>
    static LSPAny ToLSPAny(const std::vector<T>& vec) {
        LSPArray arr;
        arr.reserve(vec.size());
        for (const auto& item : vec) {
            arr.push_back(ToLSPAny(item));
        }
        return LSPAny(std::move(arr));
    }
    
    // map
    template<typename T>
    static LSPAny ToLSPAny(const std::map<string, T>& map) {
        LSPObject obj;
        for (const auto& [key, value] : map) {
            obj[key] = ToLSPAny(value);
        }
        return LSPAny(std::move(obj));
    }
    
    // optional
    template<typename T>
    static LSPAny ToLSPAny(const std::optional<T>& opt) {
        if (opt.has_value()) {
            return ToLSPAny(*opt);
        }
        return LSPAny(nullptr);
    }
    
    // === Struct 到 LSPAny 的转换（最低优先级） ===
    template<typename T>
    static typename std::enable_if<
        !std::is_arithmetic<T>::value &&
        !std::is_same<T, string>::value &&
        !std::is_same<T, const char*>::value &&
        !std::is_same<T, std::nullptr_t>::value &&
        !std::is_same<T, LSPAny>::value,
        LSPAny
    >::type ToLSPAny(const T& obj) {
        // 序列化为 JSON 字符串
        std::string json;
        auto ec = glz::write_json(obj, json);
        if (ec) {
            throw std::runtime_error("Failed to serialize to JSON");
        }
        
        // 直接解析为 LSPAny
        LSPAny result;
        ec = glz::read_json(result, json);
        if (ec) {
            throw std::runtime_error("Failed to parse JSON to LSPAny");
        }
        
        return result;
    }
    
    // === LSPAny 到基本类型的转换 ===
    
    // boolean
    static boolean BoolFromLSPAny(const LSPAny& any) {
        if (!any.is<boolean>()) {
            throw std::runtime_error("LSPAny is not a boolean");
        }
        return any.get<boolean>();
    }
    
    // 数字类型
    template<typename T>
    static typename std::enable_if<std::is_arithmetic<T>::value && !std::is_same<T, boolean>::value, T>::type
    NumberFromLSPAny(const LSPAny& any) {
        if (!any.is<decimal>()) {
            throw std::runtime_error("LSPAny is not a number");
        }
        return static_cast<T>(any.get<decimal>());
    }
    
    // string
    static string StringFromLSPAny(const LSPAny& any) {
        if (!any.is<string>()) {
            throw std::runtime_error("LSPAny is not a string");
        }
        return any.get<string>();
    }
    
    // === LSPAny 到容器类型的转换 ===
    
    // vector
    template<typename T>
    static std::vector<T> VectorFromLSPAny(const LSPAny& any) {
        if (!any.is<LSPArray>()) {
            throw std::runtime_error("LSPAny is not an array");
        }
        
        const auto& arr = any.get<LSPArray>();
        std::vector<T> result;
        result.reserve(arr.size());
        for (const auto& item : arr) {
            result.push_back(FromLSPAny<T>(item));
        }
        return result;
    }
    
    // optional
    template<typename T>
    static std::optional<T> OptionalFromLSPAny(const LSPAny& any) {
        if (any.is<std::nullptr_t>()) {
            return std::nullopt;
        }
        return FromLSPAny<T>(any);
    }
    
    // === LSPAny 到 Struct 的转换 ===
    template<typename T>
    static T FromLSPAny(const LSPAny& any) {
        return FromLSPAnyImpl<T>(any);
    }
    
private:
    // 内部实现，使用重载来处理不同类型
    
    // boolean
    static boolean FromLSPAnyImpl(const LSPAny& any, boolean*) {
        return BoolFromLSPAny(any);
    }
    
    // string
    static string FromLSPAnyImpl(const LSPAny& any, string*) {
        return StringFromLSPAny(any);
    }
    
    // 数字类型
    template<typename T>
    static typename std::enable_if<std::is_arithmetic<T>::value && !std::is_same<T, boolean>::value, T>::type
    FromLSPAnyImpl(const LSPAny& any, T*) {
        return NumberFromLSPAny<T>(any);
    }
    
    // LSPAny 自身
    static LSPAny FromLSPAnyImpl(const LSPAny& any, LSPAny*) {
        return any;
    }
    
    // struct 类型
    template<typename T>
    static typename std::enable_if<
        !std::is_arithmetic<T>::value &&
        !std::is_same<T, string>::value &&
        !std::is_same<T, LSPAny>::value,
        T
    >::type FromLSPAnyImpl(const LSPAny& any, T*) {
        // 序列化 LSPAny 为 JSON
        std::string json;
        auto ec = glz::write_json(any.value, json);
        if (ec) {
            throw std::runtime_error("Failed to serialize LSPAny to JSON");
        }
        
        // 解析 JSON 到目标类型
        T result;
        ec = glz::read_json(result, json);
        if (ec) {
            throw std::runtime_error("Failed to parse JSON to target type");
        }
        
        return result;
    }
    
    // 通过指针类型来分派
    template<typename T>
    static T FromLSPAnyImpl(const LSPAny& any) {
        return FromLSPAnyImpl(any, static_cast<T*>(nullptr));
    }
};

// ===== 便利函数（可选） =====

// 基本类型的便利函数
inline LSPAny ToLSPAny(boolean value) { return LSPConvert::ToLSPAny(value); }
inline LSPAny ToLSPAny(int value) { return LSPConvert::ToLSPAny(value); }
inline LSPAny ToLSPAny(long value) { return LSPConvert::ToLSPAny(value); }
inline LSPAny ToLSPAny(long long value) { return LSPConvert::ToLSPAny(value); }
inline LSPAny ToLSPAny(unsigned int value) { return LSPConvert::ToLSPAny(value); }
inline LSPAny ToLSPAny(unsigned long value) { return LSPConvert::ToLSPAny(value); }
inline LSPAny ToLSPAny(unsigned long long value) { return LSPConvert::ToLSPAny(value); }
inline LSPAny ToLSPAny(float value) { return LSPConvert::ToLSPAny(value); }
inline LSPAny ToLSPAny(double value) { return LSPConvert::ToLSPAny(value); }
inline LSPAny ToLSPAny(long double value) { return LSPConvert::ToLSPAny(value); }
inline LSPAny ToLSPAny(const string& str) { return LSPConvert::ToLSPAny(str); }
inline LSPAny ToLSPAny(const char* str) { return LSPConvert::ToLSPAny(str); }
inline LSPAny ToLSPAny(std::nullptr_t) { return LSPConvert::ToLSPAny(nullptr); }
inline LSPAny ToLSPAny(const LSPAny& any) { return LSPConvert::ToLSPAny(any); }

// 容器类型的便利函数
template<typename T>
LSPAny ToLSPAny(const std::vector<T>& vec) {
    return LSPConvert::ToLSPAny(vec);
}

template<typename T>
LSPAny ToLSPAny(const std::map<string, T>& map) {
    return LSPConvert::ToLSPAny(map);
}

template<typename T>
LSPAny ToLSPAny(const std::optional<T>& opt) {
    return LSPConvert::ToLSPAny(opt);
}

// struct 类型的便利函数
template<typename T>
typename std::enable_if<
    !std::is_arithmetic<T>::value &&
    !std::is_same<T, string>::value &&
    !std::is_same<T, const char*>::value &&
    !std::is_same<T, std::nullptr_t>::value &&
    !std::is_same<T, LSPAny>::value,
    LSPAny
>::type ToLSPAny(const T& value) {
    return LSPConvert::ToLSPAny(value);
}

// FromLSPAny 便利函数
template<typename T>
T FromLSPAny(const LSPAny& any) {
    return LSPConvert::FromLSPAny<T>(any);
}

// ===== 测试代码 =====

// 测试用的结构体
struct Message {
    string jsonrpc = "2.0";
    string method;
    int id = 0;
};

struct Position {
    int line;
    int character;
};

struct Range {
    Position start;
    Position end;
};

struct TextDocumentIdentifier {
    string uri;
};

struct TextDocumentPositionParams {
    TextDocumentIdentifier textDocument;
    Position position;
};

struct CompletionItem {
    string label;
    std::optional<int> kind;
    std::optional<string> detail;
    std::optional<string> documentation;
    std::optional<boolean> deprecated;
    std::optional<boolean> preselect;
    std::optional<string> sortText;
    std::optional<string> filterText;
    std::optional<string> insertText;
};

// 为测试结构体提供 glaze 元数据
template <>
struct glz::meta<Message> {
    using T = Message;
    static constexpr auto value = object(
        "jsonrpc", &T::jsonrpc,
        "method", &T::method,
        "id", &T::id
    );
};

template <>
struct glz::meta<Position> {
    using T = Position;
    static constexpr auto value = object(
        "line", &T::line,
        "character", &T::character
    );
};

template <>
struct glz::meta<Range> {
    using T = Range;
    static constexpr auto value = object(
        "start", &T::start,
        "end", &T::end
    );
};

template <>
struct glz::meta<TextDocumentIdentifier> {
    using T = TextDocumentIdentifier;
    static constexpr auto value = object(
        "uri", &T::uri
    );
};

template <>
struct glz::meta<TextDocumentPositionParams> {
    using T = TextDocumentPositionParams;
    static constexpr auto value = object(
        "textDocument", &T::textDocument,
        "position", &T::position
    );
};

template <>
struct glz::meta<CompletionItem> {
    using T = CompletionItem;
    static constexpr auto value = object(
        "label", &T::label,
        "kind", &T::kind,
        "detail", &T::detail,
        "documentation", &T::documentation,
        "deprecated", &T::deprecated,
        "preselect", &T::preselect,
        "sortText", &T::sortText,
        "filterText", &T::filterText,
        "insertText", &T::insertText
    );
};

// 测试函数
#include <iostream>

void test_basic_conversion() {
    std::cout << "=== Testing Basic Conversion ===" << std::endl;
    
    // 测试 struct 转换
    Message msg;
    msg.method = "textDocument/completion";
    msg.id = 42;
    
    // Struct -> LSPAny
    LSPAny any = ToLSPAny(msg);
    
    // 序列化查看
    std::string json;
    glz::write_json(any, json);
    std::cout << "Message as JSON: " << json << std::endl;
    
    // LSPAny -> Struct
    Message restored = FromLSPAny<Message>(any);
    std::cout << "Restored method: " << restored.method << std::endl;
    std::cout << "Restored id: " << restored.id << std::endl;
}

void test_vector_conversion() {
    std::cout << "\n=== Testing Vector Conversion ===" << std::endl;
    
    std::vector<Position> positions = {
        {10, 5},
        {20, 15},
        {30, 25}
    };
    
    // Vector -> LSPAny
    LSPAny any = ToLSPAny(positions);
    
    std::string json;
    glz::write_json(any, json);
    std::cout << "Vector as JSON: " << json << std::endl;
    
    // LSPAny -> Vector
    auto restored = LSPConvert::VectorFromLSPAny<Position>(any);
    std::cout << "Restored " << restored.size() << " positions" << std::endl;
}

void test_optional_conversion() {
    std::cout << "\n=== Testing Optional Conversion ===" << std::endl;
    
    CompletionItem item;
    item.label = "std::vector";
    item.kind = 1;
    item.detail = "template<typename T> class vector";
    
    LSPAny any = ToLSPAny(item);
    
    std::string json;
    glz::write_json(any, json);
    std::cout << "CompletionItem as JSON: " << json << std::endl;
    
    // 测试 null optional
    std::optional<string> empty_opt;
    LSPAny null_any = ToLSPAny(empty_opt);
    glz::write_json(null_any, json);
    std::cout << "Empty optional as JSON: " << json << std::endl;
}

void test_mixed_usage() {
    std::cout << "\n=== Testing Mixed Usage ===" << std::endl;
    
    // 创建复杂对象
    LSPObject obj;
    obj["message"] = ToLSPAny(Message{"2.0", "test/method", 123});
    obj["position"] = ToLSPAny(Position{10, 20});
    obj["numbers"] = ToLSPAny(std::vector<int>{1, 2, 3});
    obj["flag"] = LSPAny(true);
    obj["value"] = LSPAny(3.14);
    obj["text"] = LSPAny("Hello LSP");
    obj["empty"] = LSPAny(nullptr);
    
    LSPAny root(obj);
    
    std::string json;
    glz::write_json(root, json);
    std::cout << "Complex object: " << json << std::endl;
    
    // 提取值
    if (root.is<LSPObject>()) {
        auto& root_obj = root.get<LSPObject>();
        
        Message msg = FromLSPAny<Message>(root_obj["message"]);
        std::cout << "Extracted message method: " << msg.method << std::endl;
        
        Position pos = FromLSPAny<Position>(root_obj["position"]);
        std::cout << "Extracted position: " << pos.line << ", " << pos.character << std::endl;
    }
}

int main() {
    try {
        test_basic_conversion();
        test_vector_conversion();
        test_optional_conversion();
        test_mixed_usage();
        
        std::cout << "\nAll tests completed!" << std::endl;
    } catch (const std::exception& e) {
        std::cout << "Exception: " << e.what() << std::endl;
        return 1;
    }
    
    return 0;
}
