#include <extra2d/graphics/backends/opengl/gl_context.h>
#include <extra2d/graphics/memory/gpu_context.h>
#include <extra2d/utils/logger.h>
#include <cstring>
#include <sstream>

namespace extra2d {

// ============================================================================
// GLContext 实现
// ============================================================================

GLContext& GLContext::get() {
    static GLContext instance;
    return instance;
}

bool GLContext::init() {
    if (initialized_) {
        return true;
    }

    // 解析 OpenGL 版本
    parseVersion();

    // 加载扩展（GLAD 已在 glad.c 中完成）
    if (!loadExtensions()) {
        E2D_LOG_ERROR("Failed to load OpenGL extensions");
        return false;
    }

    initialized_ = true;

    // 标记 GPU 上下文为有效
    GPUContext::get().markValid();

    E2D_LOG_INFO("OpenGL Context initialized");
    E2D_LOG_INFO("  Version: {}", getVersionString());
    E2D_LOG_INFO("  Vendor: {}", getVendor());
    E2D_LOG_INFO("  Renderer: {}", getRenderer());
    E2D_LOG_INFO("  Max Texture Size: {}", getMaxTextureSize());
    E2D_LOG_INFO("  Max Texture Units: {}", getMaxTextureUnits());

    return true;
}

void GLContext::shutdown() {
    // 标记 GPU 上下文为无效
    GPUContext::get().markInvalid();

    initialized_ = false;
    version_ = GLVersion{};
    maxTextureSize_ = -1;
    maxTextureUnits_ = -1;
    maxVertexAttribs_ = -1;
    maxUniformBufferBindings_ = -1;
}

std::string GLContext::getVersionString() const {
    const char* version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
    return version ? version : "Unknown";
}

std::string GLContext::getVendor() const {
    const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
    return vendor ? vendor : "Unknown";
}

std::string GLContext::getRenderer() const {
    const char* renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
    return renderer ? renderer : "Unknown";
}

bool GLContext::hasExtension(const std::string& extension) const {
    GLint numExtensions = 0;
    glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);

    for (GLint i = 0; i < numExtensions; ++i) {
        const char* ext = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i));
        if (ext && extension == ext) {
            return true;
        }
    }

    return false;
}

int GLContext::getMaxTextureSize() const {
    if (maxTextureSize_ < 0) {
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize_);
    }
    return maxTextureSize_;
}

int GLContext::getMaxTextureUnits() const {
    if (maxTextureUnits_ < 0) {
        glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits_);
    }
    return maxTextureUnits_;
}

int GLContext::getMaxVertexAttribs() const {
    if (maxVertexAttribs_ < 0) {
        glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs_);
    }
    return maxVertexAttribs_;
}

int GLContext::getMaxUniformBufferBindings() const {
    if (maxUniformBufferBindings_ < 0) {
        glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings_);
    }
    return maxUniformBufferBindings_;
}

bool GLContext::hasVAO() const {
    // OpenGL 3.0+ 或 OpenGL ES 3.0+ 原生支持 VAO
    if (version_.es) {
        return version_.major >= 3;
    }
    return version_.major > 3 || (version_.major == 3 && version_.minor >= 0);
}

bool GLContext::hasFBO() const {
    // OpenGL 3.0+ 或 OpenGL ES 2.0+ 原生支持 FBO
    if (version_.es) {
        return version_.major >= 2;
    }
    return version_.major >= 3;
}

bool GLContext::hasShader() const {
    // OpenGL 2.0+ 或 OpenGL ES 2.0+ 原生支持 Shader
    if (version_.es) {
        return version_.major >= 2;
    }
    return version_.major >= 2;
}

void GLContext::parseVersion() {
    const char* versionStr = reinterpret_cast<const char*>(glGetString(GL_VERSION));
    if (!versionStr) {
        version_ = GLVersion{0, 0, false};
        return;
    }

    std::string version(versionStr);

    // 检查是否为 OpenGL ES
    if (version.find("OpenGL ES") != std::string::npos) {
        version_.es = true;
        // 解析 ES 版本号，格式如 "OpenGL ES 3.0"
        std::sscanf(version.c_str(), "OpenGL ES %d.%d", &version_.major, &version_.minor);
    } else {
        version_.es = false;
        // 解析桌面版本号，格式如 "3.3.0 NVIDIA"
        std::sscanf(version.c_str(), "%d.%d", &version_.major, &version_.minor);
    }
}

bool GLContext::loadExtensions() {
    // GLAD 已经在 glad.c 中加载了所有扩展
    // 这里可以添加额外的扩展检查
    return true;
}

} // namespace extra2d
