#include <algorithm>
#include <cmath>
#include <cstring>
#include <extra2d/graphics/backends/opengl/gl_context.h>
#include <extra2d/graphics/backends/opengl/gl_font_atlas.h>
#include <extra2d/graphics/backends/opengl/gl_framebuffer.h>
#include <extra2d/graphics/backends/opengl/gl_renderer.h>
#include <extra2d/graphics/backends/opengl/gl_texture.h>
#include <extra2d/graphics/batch/sprite_batch.h>
#include <extra2d/graphics/memory/gpu_context.h>
#include <extra2d/graphics/memory/vram_manager.h>
#include <extra2d/graphics/shader/shader_manager.h>
#include <extra2d/platform/iwindow.h>
#include <extra2d/utils/logger.h>
#include <vector>

namespace extra2d {

// VBO 初始大小（用于 VRAM 跟踪）
static constexpr size_t SHAPE_VBO_SIZE = 1024 * sizeof(float);

/**
 * @brief 构造函数，初始化OpenGL渲染器成员变量
 */
GLRenderer::GLRenderer()
    : window_(nullptr), shapeVao_(0), lineVao_(0),
      vsync_(true), shapeVertexCount_(0), currentShapeMode_(GL_TRIANGLES),
      lineVertexCount_(0), currentLineWidth_(1.0f) {
  resetStats();
  for (auto &v : shapeVertexCache_) {
    v = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
  }
  for (auto &v : lineVertexCache_) {
    v = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
  }
}

/**
 * @brief 析构函数，调用shutdown释放资源
 */
GLRenderer::~GLRenderer() { shutdown(); }

/**
 * @brief 初始化OpenGL渲染器
 * @param window 窗口指针
 * @return 初始化成功返回true，失败返回false
 */
bool GLRenderer::init(IWindow *window) {
  window_ = window;

  // 初始化 OpenGL 上下文（Switch 平台已通过 SDL2 + EGL 初始化，GLContext 会处理兼容性）
  if (!GLContext::get().init()) {
    E2D_LOG_ERROR("Failed to initialize OpenGL context");
    return false;
  }

  // 初始化精灵批渲染器
  if (!spriteBatch_.init()) {
    E2D_LOG_ERROR("Failed to initialize sprite batch");
    return false;
  }

  // 初始化形状渲染
  initShapeRendering();

  // 初始化管线状态管理
  PipelineDesc pipelineDesc;
  pipelineDesc.blendMode = BlendMode::Alpha;
  pipelineDesc.depthTest = false;
  pipelineDesc.depthWrite = false;
  if (!pipeline_.init(pipelineDesc)) {
    E2D_LOG_ERROR("Failed to initialize GLPipeline");
    return false;
  }

  // 应用初始管线状态
  pipeline_.applyAllStates();

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

  E2D_LOG_INFO("OpenGL Renderer initialized");
  E2D_LOG_INFO("OpenGL Version: {}", GLContext::get().getVersionString());

  return true;
}

/**
 * @brief 关闭渲染器，释放所有GPU资源
 */
void GLRenderer::shutdown() {
  // 标记 GPU 上下文为无效
  // 这会在销毁 OpenGL 上下文之前通知所有 GPU 资源
  GPUContext::get().markInvalid();

  spriteBatch_.shutdown();

  // 关闭 GLBuffer（自动释放 VBO）
  lineBuffer_.shutdown();
  shapeBuffer_.shutdown();

  // 删除 VAO（VAO 仍然手动管理）
  if (lineVao_ != 0) {
    glDeleteVertexArrays(1, &lineVao_);
    lineVao_ = 0;
  }
  if (shapeVao_ != 0) {
    glDeleteVertexArrays(1, &shapeVao_);
    shapeVao_ = 0;
  }

  // 关闭 OpenGL 上下文
  GLContext::get().shutdown();
}

/**
 * @brief 开始新帧，清除颜色缓冲区并重置统计信息
 * @param clearColor 清屏颜色
 */
void GLRenderer::beginFrame(const Color &clearColor) {
  // 应用管线状态
  pipeline_.applyAllStates();

  glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
  glClear(GL_COLOR_BUFFER_BIT);
  resetStats();
}

/**
 * @brief 结束当前帧，刷新所有待处理的渲染批次
 */
void GLRenderer::endFrame() {
  // 刷新所有待处理的精灵批次（自动批处理）
  if (autoBatchEnabled_ && batchActive_) {
    flush();
  }
  // 刷新所有待处理的形状批次
  flushShapeBatch();
  // 刷新所有待处理的线条批次
  flushLineBatch();
}

/**
 * @brief 设置视口区域
 * @param x 视口左下角X坐标
 * @param y 视口左下角Y坐标
 * @param width 视口宽度
 * @param height 视口高度
 */
void GLRenderer::setViewport(int x, int y, int width, int height) {
  // 使用 GLPipeline 管理视口状态
  pipeline_.setViewport(x, y, width, height);
}

/**
 * @brief 设置垂直同步
 * @param enabled true启用垂直同步，false禁用
 */
void GLRenderer::setVSync(bool enabled) {
  vsync_ = enabled;
  // 通过窗口接口设置垂直同步
  if (window_) {
    window_->setVSync(enabled);
  }
}

/**
 * @brief 设置混合模式
 * @param mode 混合模式枚举值
 */
void GLRenderer::setBlendMode(BlendMode mode) {
  // 使用 GLPipeline 管理混合状态
  pipeline_.setBlendMode(mode);
}

/**
 * @brief 设置视图投影矩阵
 * @param matrix 4x4视图投影矩阵
 */
void GLRenderer::setViewProjection(const glm::mat4 &matrix) {
  viewProjection_ = matrix;
}

/**
 * @brief 压入变换矩阵到变换栈
 * @param transform 变换矩阵
 */
void GLRenderer::pushTransform(const glm::mat4 &transform) {
  if (transformStack_.empty()) {
    transformStack_.push_back(transform);
  } else {
    transformStack_.push_back(transformStack_.back() * transform);
  }
}

/**
 * @brief 从变换栈弹出顶部变换矩阵
 */
void GLRenderer::popTransform() {
  if (!transformStack_.empty()) {
    transformStack_.pop_back();
  }
}

/**
 * @brief 获取当前累积的变换矩阵
 * @return 当前变换矩阵，如果栈为空则返回单位矩阵
 */
glm::mat4 GLRenderer::getCurrentTransform() const {
  if (transformStack_.empty()) {
    return glm::mat4(1.0f);
  }
  return transformStack_.back();
}

/**
 * @brief 创建纹理对象
 * @param width 纹理宽度
 * @param height 纹理高度
 * @param pixels 像素数据指针
 * @param channels 颜色通道数
 * @return 创建的纹理智能指针
 */
Ptr<Texture> GLRenderer::createTexture(int width, int height,
                                       const uint8_t *pixels, int channels) {
  return makePtr<GLTexture>(width, height, pixels, channels);
}

/**
 * @brief 从文件加载纹理
 * @param filepath 纹理文件路径
 * @return 加载的纹理智能指针
 */
Ptr<Texture> GLRenderer::loadTexture(const std::string &filepath) {
  return makePtr<GLTexture>(filepath);
}

/**
 * @brief 确保批处理已激活（自动批处理内部使用）
 */
void GLRenderer::ensureBatchActive() {
  if (!batchActive_) {
    spriteBatch_.begin(viewProjection_);
    batchActive_ = true;
    currentBatchTexture_ = nullptr;
    pendingSprites_.clear();
  }
}

/**
 * @brief 提交待处理的精灵（自动批处理内部使用）
 */
void GLRenderer::submitPendingSprites() {
  if (pendingSprites_.empty()) {
    return;
  }

  // 提交所有待处理的精灵
  spriteBatch_.drawBatch(*currentBatchTexture_, pendingSprites_);
  pendingSprites_.clear();
  currentBatchTexture_ = nullptr;
}

/**
 * @brief 开始手动精灵批处理（高级用法）
 * @note 一般情况下不需要调用，drawSprite/drawText 会自动管理批处理
 */
void GLRenderer::beginSpriteBatch() {
  // 如果自动批处理已激活，先提交
  if (autoBatchEnabled_ && batchActive_) {
    flush();
  }
  // 禁用自动批处理，进入手动模式
  autoBatchEnabled_ = false;
  spriteBatch_.begin(viewProjection_);
  batchActive_ = true;
}

/**
 * @brief 绘制精灵（带完整参数）
 * @param texture 纹理引用
 * @param destRect 目标矩形（屏幕坐标）
 * @param srcRect 源矩形（纹理坐标）
 * @param tint 着色颜色
 * @param rotation 旋转角度（度）
 * @param anchor 锚点位置（0-1范围）
 */
void GLRenderer::drawSprite(const Texture &texture, const Rect &destRect,
                            const Rect &srcRect, const Color &tint,
                            float rotation, const Vec2 &anchor) {
  // 自动批处理模式
  if (autoBatchEnabled_) {
    ensureBatchActive();

    // 如果纹理变化或缓冲区满，先提交当前批次
    if (currentBatchTexture_ != &texture ||
        pendingSprites_.size() >= MAX_BATCH_SPRITES) {
      submitPendingSprites();
      currentBatchTexture_ = &texture;
    }

    // 创建精灵数据
    SpriteData data;
    data.position = Vec2(destRect.origin.x, destRect.origin.y);
    data.size = Vec2(destRect.size.width, destRect.size.height);

    Texture *tex = const_cast<Texture *>(&texture);
    float texW = static_cast<float>(tex->getWidth());
    float texH = static_cast<float>(tex->getHeight());

    // 纹理坐标计算
    float u1 = srcRect.origin.x / texW;
    float u2 = (srcRect.origin.x + srcRect.size.width) / texW;
    float v1 = srcRect.origin.y / texH;
    float v2 = (srcRect.origin.y + srcRect.size.height) / texH;

    data.uvRect = Rect(Vec2(glm::min(u1, u2), glm::min(v1, v2)),
                       Size(glm::abs(u2 - u1), glm::abs(v2 - v1)));

    data.color = tint;
    data.rotation = rotation * 3.14159f / 180.0f;
    data.pivot = Vec2(anchor.x, anchor.y);

    // 添加到待处理列表
    pendingSprites_.push_back(data);
  } else {
    // 手动批处理模式
    SpriteData data;
    data.position = Vec2(destRect.origin.x, destRect.origin.y);
    data.size = Vec2(destRect.size.width, destRect.size.height);

    Texture *tex = const_cast<Texture *>(&texture);
    float texW = static_cast<float>(tex->getWidth());
    float texH = static_cast<float>(tex->getHeight());

    float u1 = srcRect.origin.x / texW;
    float u2 = (srcRect.origin.x + srcRect.size.width) / texW;
    float v1 = srcRect.origin.y / texH;
    float v2 = (srcRect.origin.y + srcRect.size.height) / texH;

    data.uvRect = Rect(Vec2(glm::min(u1, u2), glm::min(v1, v2)),
                       Size(glm::abs(u2 - u1), glm::abs(v2 - v1)));

    data.color = tint;
    data.rotation = rotation * 3.14159f / 180.0f;
    data.pivot = Vec2(anchor.x, anchor.y);

    spriteBatch_.draw(texture, data);
  }
}

/**
 * @brief 绘制精灵（简化版本）
 * @param texture 纹理引用
 * @param position 绘制位置
 * @param tint 着色颜色
 */
void GLRenderer::drawSprite(const Texture &texture, const Vec2 &position,
                            const Color &tint) {
  Rect destRect(position.x, position.y, static_cast<float>(texture.getWidth()),
                static_cast<float>(texture.getHeight()));
  Rect srcRect(0, 0, static_cast<float>(texture.getWidth()),
               static_cast<float>(texture.getHeight()));
  drawSprite(texture, destRect, srcRect, tint, 0.0f, Vec2(0, 0));
}

/**
 * @brief 结束手动精灵批处理并提交绘制
 * @note 一般情况下不需要调用
 */
void GLRenderer::endSpriteBatch() {
  if (autoBatchEnabled_) {
    // 自动模式下，只是标记批处理结束
    flush();
  } else {
    // 手动模式下，提交批处理并恢复自动模式
    spriteBatch_.end();
    stats_.drawCalls += spriteBatch_.getDrawCallCount();
    batchActive_ = false;
    autoBatchEnabled_ = true;
  }
}

/**
 * @brief 立即提交当前批处理
 * @note 手动控制批处理提交时机，一般情况下不需要调用
 */
void GLRenderer::flush() {
  if (autoBatchEnabled_ && batchActive_) {
    submitPendingSprites();
    spriteBatch_.end();
    stats_.drawCalls += spriteBatch_.getDrawCallCount();
    batchActive_ = false;
    currentBatchTexture_ = nullptr;
  }
}

/**
 * @brief 绘制线段
 * @param start 起点坐标
 * @param end 终点坐标
 * @param color 线条颜色
 * @param width 线条宽度
 */
void GLRenderer::drawLine(const Vec2 &start, const Vec2 &end,
                          const Color &color, float width) {
  // 如果线宽改变，需要先刷新线条批次
  if (width != currentLineWidth_) {
    flushLineBatch();
    currentLineWidth_ = width;
  }

  // 添加两个顶点到线条缓冲区
  addLineVertex(start.x, start.y, color);
  addLineVertex(end.x, end.y, color);
}

void GLRenderer::drawRect(const Rect &rect, const Color &color, float width) {
  // 如果线宽改变，需要先刷新线条批次
  if (width != currentLineWidth_) {
    flushLineBatch();
    currentLineWidth_ = width;
  }

  float x1 = rect.origin.x;
  float y1 = rect.origin.y;
  float x2 = rect.origin.x + rect.size.width;
  float y2 = rect.origin.y + rect.size.height;

  // 4条线段 = 8个顶点
  // 上边
  addLineVertex(x1, y1, color);
  addLineVertex(x2, y1, color);
  // 右边
  addLineVertex(x2, y1, color);
  addLineVertex(x2, y2, color);
  // 下边
  addLineVertex(x2, y2, color);
  addLineVertex(x1, y2, color);
  // 左边
  addLineVertex(x1, y2, color);
  addLineVertex(x1, y1, color);
}

/**
 * @brief 填充矩形
 * @param rect 矩形区域
 * @param color 填充颜色
 */
void GLRenderer::fillRect(const Rect &rect, const Color &color) {
  // 提交当前批次（如果模式不同）
  submitShapeBatch(GL_TRIANGLES);

  // 添加两个三角形组成矩形（6个顶点）
  float x1 = rect.origin.x;
  float y1 = rect.origin.y;
  float x2 = rect.origin.x + rect.size.width;
  float y2 = rect.origin.y + rect.size.height;

  // 三角形1: (x1,y1), (x2,y1), (x2,y2)
  addShapeVertex(x1, y1, color);
  addShapeVertex(x2, y1, color);
  addShapeVertex(x2, y2, color);

  // 三角形2: (x1,y1), (x2,y2), (x1,y2)
  addShapeVertex(x1, y1, color);
  addShapeVertex(x2, y2, color);
  addShapeVertex(x1, y2, color);
}

/**
 * @brief 绘制圆形边框
 * @param center 圆心坐标
 * @param radius 半径
 * @param color 边框颜色
 * @param segments 分段数
 * @param width 线条宽度
 */
void GLRenderer::drawCircle(const Vec2 &center, float radius,
                            const Color &color, int segments, float width) {
  // 限制段数不超过缓存大小
  if (segments > static_cast<int>(MAX_CIRCLE_SEGMENTS)) {
    segments = static_cast<int>(MAX_CIRCLE_SEGMENTS);
  }

  // 如果线宽改变，需要先刷新线条批次
  if (width != currentLineWidth_) {
    flushLineBatch();
    currentLineWidth_ = width;
  }

  // 使用线条批处理绘制圆形
  for (int i = 0; i < segments; ++i) {
    float angle1 =
        2.0f * 3.14159f * static_cast<float>(i) / static_cast<float>(segments);
    float angle2 = 2.0f * 3.14159f * static_cast<float>(i + 1) /
                   static_cast<float>(segments);

    addLineVertex(center.x + radius * cosf(angle1),
                  center.y + radius * sinf(angle1), color);
    addLineVertex(center.x + radius * cosf(angle2),
                  center.y + radius * sinf(angle2), color);
  }
}

/**
 * @brief 填充圆形
 * @param center 圆心坐标
 * @param radius 半径
 * @param color 填充颜色
 * @param segments 分段数
 */
void GLRenderer::fillCircle(const Vec2 &center, float radius,
                            const Color &color, int segments) {
  // 限制段数不超过缓存大小
  if (segments > static_cast<int>(MAX_CIRCLE_SEGMENTS)) {
    segments = static_cast<int>(MAX_CIRCLE_SEGMENTS);
  }

  // 提交当前批次（如果模式不同）
  submitShapeBatch(GL_TRIANGLES);

  // 使用三角形扇形填充圆
  // 中心点 + 边缘点
  for (int i = 0; i < segments; ++i) {
    float angle1 =
        2.0f * 3.14159f * static_cast<float>(i) / static_cast<float>(segments);
    float angle2 = 2.0f * 3.14159f * static_cast<float>(i + 1) /
                   static_cast<float>(segments);

    // 每个三角形：中心 -> 边缘点1 -> 边缘点2
    addShapeVertex(center.x, center.y, color);
    addShapeVertex(center.x + radius * cosf(angle1),
                   center.y + radius * sinf(angle1), color);
    addShapeVertex(center.x + radius * cosf(angle2),
                   center.y + radius * sinf(angle2), color);
  }
}

/**
 * @brief 绘制三角形边框
 * @param p1 第一个顶点
 * @param p2 第二个顶点
 * @param p3 第三个顶点
 * @param color 边框颜色
 * @param width 线条宽度
 */
void GLRenderer::drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
                              const Color &color, float width) {
  drawLine(p1, p2, color, width);
  drawLine(p2, p3, color, width);
  drawLine(p3, p1, color, width);
}

/**
 * @brief 填充三角形
 * @param p1 第一个顶点
 * @param p2 第二个顶点
 * @param p3 第三个顶点
 * @param color 填充颜色
 */
void GLRenderer::fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
                              const Color &color) {
  submitShapeBatch(GL_TRIANGLES);

  addShapeVertex(p1.x, p1.y, color);
  addShapeVertex(p2.x, p2.y, color);
  addShapeVertex(p3.x, p3.y, color);
}

/**
 * @brief 绘制多边形边框
 * @param points 顶点数组
 * @param color 边框颜色
 * @param width 线条宽度
 */
void GLRenderer::drawPolygon(const std::vector<Vec2> &points,
                             const Color &color, float width) {
  if (points.size() < 2)
    return;

  // 如果线宽改变，需要先刷新线条批次
  if (width != currentLineWidth_) {
    flushLineBatch();
    currentLineWidth_ = width;
  }

  // 绘制所有边
  for (size_t i = 0; i < points.size(); ++i) {
    const Vec2 &p1 = points[i];
    const Vec2 &p2 = points[(i + 1) % points.size()];
    addLineVertex(p1.x, p1.y, color);
    addLineVertex(p2.x, p2.y, color);
  }
}

/**
 * @brief 填充多边形
 * @param points 顶点数组
 * @param color 填充颜色
 */
void GLRenderer::fillPolygon(const std::vector<Vec2> &points,
                             const Color &color) {
  if (points.size() < 3)
    return;

  submitShapeBatch(GL_TRIANGLES);

  // 使用三角形扇形填充
  // 从第一个点开始，每两个相邻点组成一个三角形
  for (size_t i = 1; i < points.size() - 1; ++i) {
    addShapeVertex(points[0].x, points[0].y, color);
    addShapeVertex(points[i].x, points[i].y, color);
    addShapeVertex(points[i + 1].x, points[i + 1].y, color);
  }
}

/**
 * @brief 创建字体图集
 * @param filepath 字体文件路径
 * @param fontSize 字体大小
 * @param useSDF 是否使用SDF渲染
 * @return 创建的字体图集智能指针
 */
Ptr<FontAtlas> GLRenderer::createFontAtlas(const std::string &filepath,
                                           int fontSize, bool useSDF) {
  return makePtr<GLFontAtlas>(filepath, fontSize, useSDF);
}

/**
 * @brief 绘制文本（使用Vec2位置）
 * @param font 字体图集引用
 * @param text 文本内容
 * @param position 绘制位置
 * @param color 文本颜色
 */
void GLRenderer::drawText(const FontAtlas &font, const std::string &text,
                          const Vec2 &position, const Color &color) {
  drawText(font, text, position.x, position.y, color);
}

/**
 * @brief 绘制文本（使用浮点坐标）
 * @param font 字体图集引用
 * @param text 文本内容
 * @param x X坐标
 * @param y Y坐标
 * @param color 文本颜色
 */
void GLRenderer::drawText(const FontAtlas &font, const std::string &text,
                          float x, float y, const Color &color) {
  float cursorX = x;
  float cursorY = y;
  float baselineY = cursorY + font.getAscent();

  // 确保批处理已激活（自动批处理）
  if (autoBatchEnabled_) {
    ensureBatchActive();
  }

  // 检查纹理变化，如果纹理不同则先提交当前批次
  if (autoBatchEnabled_ && currentBatchTexture_ != nullptr &&
      currentBatchTexture_ != font.getTexture()) {
    submitPendingSprites();
  }
  if (autoBatchEnabled_) {
    currentBatchTexture_ = font.getTexture();
  }

  // 收集所有字符数据用于批处理
  std::vector<SpriteData> sprites;
  sprites.reserve(text.size()); // 预分配空间

  for (char c : text) {
    char32_t codepoint = static_cast<char32_t>(static_cast<unsigned char>(c));
    if (codepoint == '\n') {
      // 换行时，将当前行添加到待处理列表
      if (!sprites.empty()) {
        if (autoBatchEnabled_) {
          pendingSprites_.insert(pendingSprites_.end(), sprites.begin(),
                                 sprites.end());
        } else {
          // 手动模式直接提交
          spriteBatch_.drawBatch(*font.getTexture(), sprites);
        }
        sprites.clear();
      }
      cursorX = x;
      cursorY += font.getLineHeight();
      baselineY = cursorY + font.getAscent();
      continue;
    }

    const Glyph *glyph = font.getGlyph(codepoint);
    if (glyph) {
      float penX = cursorX;
      cursorX += glyph->advance;

      // 使用 epsilon 比较浮点数，避免精度问题
      constexpr float EPSILON = 0.001f;
      if (glyph->width < EPSILON || glyph->height < EPSILON) {
        continue;
      }

      // 计算字形位置
      // bearingX: 水平偏移（从左边缘到字形左边缘）
      // bearingY: 垂直偏移（从基线到字形顶部，通常为负值）
      float xPos = penX + glyph->bearingX;
      float yPos = baselineY + glyph->bearingY;

      SpriteData data;
      // 设置精灵中心位置（精灵批处理使用中心点）
      data.position =
          Vec2(xPos + glyph->width * 0.5f, yPos + glyph->height * 0.5f);
      data.size = Vec2(glyph->width, glyph->height);
      data.uvRect = Rect(Vec2(glyph->u0, glyph->v0),
                         Size(glyph->u1 - glyph->u0, glyph->v1 - glyph->v0));
      data.color = color;
      data.rotation = 0.0f;
      // pivot (0.5, 0.5) 表示中心点，这样 position 就是精灵中心
      data.pivot = Vec2(0.5f, 0.5f);

      sprites.push_back(data);

      // 自动批处理：如果缓冲区满，先提交当前批次
      if (autoBatchEnabled_ && sprites.size() >= MAX_BATCH_SPRITES) {
        pendingSprites_.insert(pendingSprites_.end(), sprites.begin(),
                               sprites.end());
        sprites.clear();
      }
    }
  }

  // 提交剩余的字符
  if (!sprites.empty()) {
    if (autoBatchEnabled_) {
      pendingSprites_.insert(pendingSprites_.end(), sprites.begin(),
                             sprites.end());
    } else {
      // 手动模式下直接提交
      spriteBatch_.drawBatch(*font.getTexture(), sprites);
    }
  }
}

/**
 * @brief 重置渲染统计信息
 */
void GLRenderer::resetStats() { stats_ = Stats{}; }

/**
 * @brief 初始化形状渲染所需的OpenGL资源（VAO、VBO、着色器）
 */
void GLRenderer::initShapeRendering() {
  // 从ShaderManager获取形状着色器
  shapeShader_ = ShaderManager::getInstance().getBuiltin("shape");
  if (!shapeShader_) {
    E2D_LOG_WARN("Failed to get builtin shape shader, loading from manager");
    if (!ShaderManager::getInstance().isInitialized()) {
      E2D_LOG_ERROR("ShaderManager not initialized, shape rendering may fail");
    }
  }

  // 初始化形状 GLBuffer（使用 Dynamic 使用模式，因为每帧都会更新）
  BufferDesc shapeBufferDesc;
  shapeBufferDesc.type = BufferType::Vertex;
  shapeBufferDesc.usage = BufferUsage::Dynamic;
  shapeBufferDesc.size = MAX_SHAPE_VERTICES * sizeof(ShapeVertex);
  if (!shapeBuffer_.init(shapeBufferDesc)) {
    E2D_LOG_ERROR("Failed to initialize shape buffer");
  }

  // 创建形状 VAO（手动管理，用于顶点属性配置）
  glGenVertexArrays(1, &shapeVao_);
  glBindVertexArray(shapeVao_);
  shapeBuffer_.bind();

  // 位置属性 (location = 0)
  glEnableVertexAttribArray(0);
  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(ShapeVertex),
                        reinterpret_cast<void *>(offsetof(ShapeVertex, x)));

  // 颜色属性 (location = 1)
  glEnableVertexAttribArray(1);
  glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(ShapeVertex),
                        reinterpret_cast<void *>(offsetof(ShapeVertex, r)));

  glBindVertexArray(0);

  // 初始化线条 GLBuffer（使用 Dynamic 使用模式，因为每帧都会更新）
  BufferDesc lineBufferDesc;
  lineBufferDesc.type = BufferType::Vertex;
  lineBufferDesc.usage = BufferUsage::Dynamic;
  lineBufferDesc.size = MAX_LINE_VERTICES * sizeof(ShapeVertex);
  if (!lineBuffer_.init(lineBufferDesc)) {
    E2D_LOG_ERROR("Failed to initialize line buffer");
  }

  // 创建线条 VAO（手动管理，用于顶点属性配置）
  glGenVertexArrays(1, &lineVao_);
  glBindVertexArray(lineVao_);
  lineBuffer_.bind();

  // 位置属性 (location = 0)
  glEnableVertexAttribArray(0);
  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(ShapeVertex),
                        reinterpret_cast<void *>(offsetof(ShapeVertex, x)));

  // 颜色属性 (location = 1)
  glEnableVertexAttribArray(1);
  glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(ShapeVertex),
                        reinterpret_cast<void *>(offsetof(ShapeVertex, r)));

  glBindVertexArray(0);
}

/**
 * @brief 添加形状顶点到缓存
 * @param x X坐标
 * @param y Y坐标
 * @param color 顶点颜色
 */
void GLRenderer::addShapeVertex(float x, float y, const Color &color) {
  if (shapeVertexCount_ >= MAX_SHAPE_VERTICES) {
    flushShapeBatch();
  }

  glm::vec4 pos(x, y, 0.0f, 1.0f);
  if (!transformStack_.empty()) {
    pos = transformStack_.back() * pos;
  }

  ShapeVertex &v = shapeVertexCache_[shapeVertexCount_++];
  v.x = pos.x;
  v.y = pos.y;
  v.r = color.r;
  v.g = color.g;
  v.b = color.b;
  v.a = color.a;
}

/**
 * @brief 添加线条顶点到缓存
 * @param x X坐标
 * @param y Y坐标
 * @param color 顶点颜色
 */
void GLRenderer::addLineVertex(float x, float y, const Color &color) {
  if (lineVertexCount_ >= MAX_LINE_VERTICES) {
    flushLineBatch();
  }

  glm::vec4 pos(x, y, 0.0f, 1.0f);
  if (!transformStack_.empty()) {
    pos = transformStack_.back() * pos;
  }

  ShapeVertex &v = lineVertexCache_[lineVertexCount_++];
  v.x = pos.x;
  v.y = pos.y;
  v.r = color.r;
  v.g = color.g;
  v.b = color.b;
  v.a = color.a;
}

/**
 * @brief 提交形状批次（如果需要切换绘制模式）
 * @param mode OpenGL绘制模式
 */
void GLRenderer::submitShapeBatch(GLenum mode) {
  if (shapeVertexCount_ == 0)
    return;

  // 如果模式改变，先刷新
  if (currentShapeMode_ != mode && shapeVertexCount_ > 0) {
    flushShapeBatch();
  }
  currentShapeMode_ = mode;
}

/**
 * @brief 刷新形状批次，执行实际的OpenGL绘制调用
 */
void GLRenderer::flushShapeBatch() {
  if (shapeVertexCount_ == 0)
    return;

  if (shapeShader_) {
    shapeShader_->bind();
    shapeShader_->setMat4("u_viewProjection", viewProjection_);
  }

  // 使用 GLBuffer::updateData() 更新缓冲区数据
  shapeBuffer_.updateData(shapeVertexCache_.data(), 0,
                          shapeVertexCount_ * sizeof(ShapeVertex));

  glBindVertexArray(shapeVao_);
  glDrawArrays(currentShapeMode_, 0, static_cast<GLsizei>(shapeVertexCount_));

  stats_.drawCalls++;
  stats_.triangleCount += static_cast<uint32_t>(shapeVertexCount_ / 3);

  shapeVertexCount_ = 0;
}

/**
 * @brief 刷新线条批次，执行实际的OpenGL绘制调用
 */
void GLRenderer::flushLineBatch() {
  if (lineVertexCount_ == 0)
    return;

  // 先刷新形状批次
  flushShapeBatch();

  glLineWidth(currentLineWidth_);
  if (shapeShader_) {
    shapeShader_->bind();
    shapeShader_->setMat4("u_viewProjection", viewProjection_);
  }

  // 使用 GLBuffer::updateData() 更新缓冲区数据
  lineBuffer_.updateData(lineVertexCache_.data(), 0,
                         lineVertexCount_ * sizeof(ShapeVertex));

  glBindVertexArray(lineVao_);
  glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(lineVertexCount_));

  stats_.drawCalls++;

  lineVertexCount_ = 0;
}

/**
 * @brief 创建帧缓冲对象
 * @param desc 帧缓冲描述
 * @return 创建的帧缓冲智能指针
 */
Ptr<GLFramebuffer> GLRenderer::createFramebuffer(const FramebufferDesc& desc) {
  auto framebuffer = makePtr<GLFramebuffer>();
  if (!framebuffer->init(desc)) {
    E2D_LOG_ERROR("Failed to create framebuffer");
    return nullptr;
  }
  return framebuffer;
}

/**
 * @brief 绑定帧缓冲（作为渲染目标）
 * @param framebuffer 帧缓冲对象指针，传入 nullptr 则绑定默认帧缓冲
 */
void GLRenderer::bindFramebuffer(GLFramebuffer* framebuffer) {
  // 先刷新所有待处理的渲染批次
  flush();
  flushShapeBatch();
  flushLineBatch();

  if (framebuffer == nullptr) {
    // 绑定默认帧缓冲（ID 为 0）
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    currentFramebuffer_ = nullptr;
    E2D_LOG_TRACE("Bound default framebuffer (0)");
  } else {
    // 绑定自定义帧缓冲
    framebuffer->bind();
    currentFramebuffer_ = framebuffer;
    E2D_LOG_TRACE("Bound custom framebuffer (ID: {})", framebuffer->getFboID());
  }
}

/**
 * @brief 解绑帧缓冲（恢复到默认帧缓冲）
 */
void GLRenderer::unbindFramebuffer() {
  bindFramebuffer(nullptr);
}

/**
 * @brief 获取默认帧缓冲
 * @return 默认帧缓冲智能指针
 */
Ptr<GLFramebuffer> GLRenderer::getDefaultFramebuffer() const {
  if (!defaultFramebuffer_) {
    // 延迟创建默认帧缓冲对象（代表系统默认帧缓冲，ID 为 0）
    defaultFramebuffer_ = makePtr<GLFramebuffer>();
    // 注意：默认帧缓冲不需要显式初始化，它的 FBO ID 为 0
  }
  return defaultFramebuffer_;
}

/**
 * @brief 清除当前绑定的帧缓冲
 * @param color 清除颜色
 * @param clearColor 是否清除颜色缓冲
 * @param clearDepth 是否清除深度缓冲
 * @param clearStencil 是否清除模板缓冲
 */
void GLRenderer::clearFramebuffer(const Color& color, bool clearColor,
                                  bool clearDepth, bool clearStencil) {
  GLbitfield mask = 0;

  if (clearColor) {
    glClearColor(color.r, color.g, color.b, color.a);
    mask |= GL_COLOR_BUFFER_BIT;
  }

  if (clearDepth) {
    mask |= GL_DEPTH_BUFFER_BIT;
  }

  if (clearStencil) {
    mask |= GL_STENCIL_BUFFER_BIT;
  }

  if (mask != 0) {
    glClear(mask);
  }
}

} // namespace extra2d
