#pragma once

#include <extra2d/graphics/backends/opengl/gl_buffer.h>
#include <extra2d/graphics/backends/opengl/gl_framebuffer.h>
#include <extra2d/graphics/backends/opengl/gl_pipeline.h>
#include <extra2d/graphics/backends/opengl/gl_sprite_batch.h>
#include <extra2d/graphics/core/render_backend.h>
#include <extra2d/graphics/shader/shader_interface.h>

#include <array>
#include <glad/glad.h>
#include <vector>

namespace extra2d {

// 前向声明
class IWindow;
class GLContext;
class GLFramebuffer;

// ============================================================================
// OpenGL 渲染器实现
// ============================================================================
class GLRenderer : public RenderBackend {
public:
  GLRenderer();
  ~GLRenderer() override;

  // RenderBackend 接口实现
  bool init(IWindow* window) override;
  void shutdown() override;

  void beginFrame(const Color &clearColor) override;
  void endFrame() override;
  void setViewport(int x, int y, int width, int height) override;
  void setVSync(bool enabled) override;

  void setBlendMode(BlendMode mode) override;
  void setViewProjection(const glm::mat4 &matrix) override;

  // 变换矩阵栈
  void pushTransform(const glm::mat4 &transform) override;
  void popTransform() override;
  glm::mat4 getCurrentTransform() const override;

  Ptr<Texture> createTexture(int width, int height, const uint8_t *pixels,
                             int channels) override;
  Ptr<Texture> loadTexture(const std::string &filepath) override;

  void beginSpriteBatch() override;
  void drawSprite(const Texture &texture, const Rect &destRect,
                  const Rect &srcRect, const Color &tint, float rotation,
                  const Vec2 &anchor) override;
  void drawSprite(const Texture &texture, const Vec2 &position,
                  const Color &tint) override;
  void endSpriteBatch() override;
  void flush() override;

  void drawLine(const Vec2 &start, const Vec2 &end, const Color &color,
                float width) override;
  void drawRect(const Rect &rect, const Color &color, float width) override;
  void fillRect(const Rect &rect, const Color &color) override;
  void drawCircle(const Vec2 &center, float radius, const Color &color,
                  int segments, float width) override;
  void fillCircle(const Vec2 &center, float radius, const Color &color,
                  int segments) override;
  void drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
                    const Color &color, float width) override;
  void fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
                    const Color &color) override;
  void drawPolygon(const std::vector<Vec2> &points, const Color &color,
                   float width) override;
  void fillPolygon(const std::vector<Vec2> &points,
                   const Color &color) override;

  Ptr<FontAtlas> createFontAtlas(const std::string &filepath, int fontSize,
                                 bool useSDF = false) override;
  void drawText(const FontAtlas &font, const std::string &text,
                const Vec2 &position, const Color &color) override;
  void drawText(const FontAtlas &font, const std::string &text, float x,
                float y, const Color &color) override;

  Stats getStats() const override { return stats_; }
  void resetStats() override;

  // GLFramebuffer 相关方法

  /**
   * @brief 创建帧缓冲对象
   * @param desc 帧缓冲描述
   * @return 创建的帧缓冲智能指针
   */
  Ptr<GLFramebuffer> createFramebuffer(const FramebufferDesc& desc);

  /**
   * @brief 绑定帧缓冲（作为渲染目标）
   * @param framebuffer 帧缓冲对象指针，传入 nullptr 则绑定默认帧缓冲
   */
  void bindFramebuffer(GLFramebuffer* framebuffer);

  /**
   * @brief 解绑帧缓冲（恢复到默认帧缓冲）
   */
  void unbindFramebuffer();

  /**
   * @brief 获取默认帧缓冲
   * @return 默认帧缓冲智能指针
   */
  Ptr<GLFramebuffer> getDefaultFramebuffer() const;

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

private:
  // 形状批处理常量
  static constexpr size_t MAX_CIRCLE_SEGMENTS = 128;
  static constexpr size_t MAX_SHAPE_VERTICES = 8192; // 最大形状顶点数
  static constexpr size_t MAX_LINE_VERTICES = 16384; // 最大线条顶点数

  // 形状顶点结构（包含颜色）
  struct ShapeVertex {
    float x, y;
    float r, g, b, a;
  };

  IWindow* window_;
  GLSpriteBatch spriteBatch_;
  Ptr<IShader> shapeShader_;

  GLuint shapeVao_;  // 形状 VAO（手动管理，用于顶点属性配置）
  GLBuffer shapeBuffer_;  // 形状 VBO（使用 GLBuffer 管理）
  GLuint lineVao_;   // 线条 VAO（手动管理，用于顶点属性配置）
  GLBuffer lineBuffer_;   // 线条 VBO（使用 GLBuffer 管理）

  glm::mat4 viewProjection_;
  std::vector<glm::mat4> transformStack_;
  Stats stats_;
  bool vsync_;

  // 形状批处理缓冲区（预分配，避免每帧内存分配）
  std::array<ShapeVertex, MAX_SHAPE_VERTICES> shapeVertexCache_;
  size_t shapeVertexCount_ = 0;
  GLenum currentShapeMode_ = GL_TRIANGLES;

  // 线条批处理缓冲区
  std::array<ShapeVertex, MAX_LINE_VERTICES> lineVertexCache_;
  size_t lineVertexCount_ = 0;
  float currentLineWidth_ = 1.0f;

  // OpenGL 管线状态管理
  GLPipeline pipeline_;

  // 自动批处理状态
  bool batchActive_ = false;           // 批处理是否激活
  bool autoBatchEnabled_ = true;       // 是否启用自动批处理
  const Texture* currentBatchTexture_ = nullptr;  // 当前批处理的纹理
  std::vector<SpriteData> pendingSprites_;        // 待提交的精灵
  static constexpr size_t MAX_BATCH_SPRITES = 1000; // 最大批处理精灵数

  // 帧缓冲管理
  mutable Ptr<GLFramebuffer> defaultFramebuffer_;  // 默认帧缓冲（延迟创建）
  GLFramebuffer* currentFramebuffer_ = nullptr;    // 当前绑定的帧缓冲

  void initShapeRendering();
  void ensureBatchActive();            // 确保批处理已激活
  void submitPendingSprites();         // 提交待处理的精灵
  void flushShapeBatch();
  void flushLineBatch();
  void addShapeVertex(float x, float y, const Color &color);
  void addLineVertex(float x, float y, const Color &color);
  void submitShapeBatch(GLenum mode);
};

} // namespace extra2d
