#pragma once

#include <extra2d/core/color.h>
#include <extra2d/core/math_types.h>
#include <extra2d/core/types.h>
#include <extra2d/graphics/resources/pipeline.h>
#include <glm/mat4x4.hpp>

namespace extra2d {

// 前向声明
class IWindow;
class Texture;
class FontAtlas;
class Shader;

// BlendMode 定义在 pipeline.h 中

// ============================================================================
// 渲染后端抽象接口
// ============================================================================
class RenderBackend {
public:
  virtual ~RenderBackend() = default;

  // ------------------------------------------------------------------------
  // 生命周期
  // ------------------------------------------------------------------------
  virtual bool init(IWindow* window) = 0;
  virtual void shutdown() = 0;

  // ------------------------------------------------------------------------
  // 帧管理
  // ------------------------------------------------------------------------
  virtual void beginFrame(const Color &clearColor) = 0;
  virtual void endFrame() = 0;
  virtual void setViewport(int x, int y, int width, int height) = 0;
  virtual void setVSync(bool enabled) = 0;

  // ------------------------------------------------------------------------
  // 状态设置
  // ------------------------------------------------------------------------
  virtual void setBlendMode(BlendMode mode) = 0;
  virtual void setViewProjection(const glm::mat4 &matrix) = 0;

  // ------------------------------------------------------------------------
  // 变换矩阵栈
  // ------------------------------------------------------------------------
  virtual void pushTransform(const glm::mat4 &transform) = 0;
  virtual void popTransform() = 0;
  virtual glm::mat4 getCurrentTransform() const = 0;

  // ------------------------------------------------------------------------
  // 纹理
  // ------------------------------------------------------------------------
  virtual Ptr<Texture> createTexture(int width, int height,
                                     const uint8_t *pixels, int channels) = 0;
  virtual Ptr<Texture> loadTexture(const std::string &filepath) = 0;

  // ------------------------------------------------------------------------
  // 精灵批渲染
  // ------------------------------------------------------------------------
  /**
   * @brief 开始手动精灵批处理（高级用法）
   * @note 一般情况下不需要调用，drawSprite/drawText 会自动管理批处理
   */
  virtual void beginSpriteBatch() = 0;
  virtual void drawSprite(const Texture &texture, const Rect &destRect,
                          const Rect &srcRect, const Color &tint,
                          float rotation, const Vec2 &anchor) = 0;
  virtual void drawSprite(const Texture &texture, const Vec2 &position,
                          const Color &tint) = 0;
  virtual void endSpriteBatch() = 0;

  /**
   * @brief 立即提交当前批处理
   * @note 手动控制批处理提交时机，一般情况下不需要调用
   */
  virtual void flush() = 0;

  // ------------------------------------------------------------------------
  // 形状渲染
  // ------------------------------------------------------------------------
  virtual void drawLine(const Vec2 &start, const Vec2 &end, const Color &color,
                        float width = 1.0f) = 0;
  virtual void drawRect(const Rect &rect, const Color &color,
                        float width = 1.0f) = 0;
  virtual void fillRect(const Rect &rect, const Color &color) = 0;
  virtual void drawCircle(const Vec2 &center, float radius, const Color &color,
                          int segments = 32, float width = 1.0f) = 0;
  virtual void fillCircle(const Vec2 &center, float radius, const Color &color,
                          int segments = 32) = 0;
  virtual void drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
                            const Color &color, float width = 1.0f) = 0;
  virtual void fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
                            const Color &color) = 0;
  virtual void drawPolygon(const std::vector<Vec2> &points, const Color &color,
                           float width = 1.0f) = 0;
  virtual void fillPolygon(const std::vector<Vec2> &points,
                           const Color &color) = 0;

  // ------------------------------------------------------------------------
  // 文字渲染
  // ------------------------------------------------------------------------
  virtual Ptr<FontAtlas> createFontAtlas(const std::string &filepath,
                                         int fontSize, bool useSDF = false) = 0;
  virtual void drawText(const FontAtlas &font, const std::string &text,
                        const Vec2 &position, const Color &color) = 0;
  virtual void drawText(const FontAtlas &font, const std::string &text, float x,
                        float y, const Color &color) = 0;

  // ------------------------------------------------------------------------
  // 统计信息
  // ------------------------------------------------------------------------
  struct Stats {
    uint32_t drawCalls = 0;
    uint32_t triangleCount = 0;
    uint32_t textureBinds = 0;
    uint32_t shaderBinds = 0;
  };
  virtual Stats getStats() const = 0;
  virtual void resetStats() = 0;
};

} // namespace extra2d
