#pragma once

#include <extra2d/core/types.h>
#include <extra2d/core/math_types.h>
#include <extra2d/core/color.h>
#include <extra2d/graphics/texture/texture.h>

#include <glm/mat4x4.hpp>

#include <array>
#include <vector>
#include <cstdint>

namespace extra2d {

// ============================================================================
// 三角函数查表 - 避免每帧计算 sin/cos
// ============================================================================
class TrigLookup {
public:
    TrigLookup();
    
    // 通过角度(0-360)获取 sin/cos
    float sin(int angle) const;
    float cos(int angle) const;
    
    // 通过弧度获取 sin/cos
    float sinRad(float rad) const;
    float cosRad(float rad) const;

private:
    static constexpr int TABLE_SIZE = 360 * 4; // 0.25度精度
    std::array<float, TABLE_SIZE> sinTable_;
    std::array<float, TABLE_SIZE> cosTable_;
};

// ============================================================================
// 精灵批次数据 - 后端无关
// ============================================================================
struct SpriteVertex {
    Vec2 position;
    Vec2 texCoord;
    Color color;
};

struct SpriteData {
    Vec2 position;
    Vec2 size;
    float rotation;
    Vec2 pivot;
    Color color;
    const Texture* texture;
    Rect uvRect;
};

// ============================================================================
// 通用精灵批处理 - 后端无关
// 负责：顶点生成、批次管理、三角函数查表
// ============================================================================
class SpriteBatch {
public:
    static constexpr size_t MAX_SPRITES = 10000;
    static constexpr size_t VERTICES_PER_SPRITE = 4;
    static constexpr size_t INDICES_PER_SPRITE = 6;
    static constexpr size_t MAX_VERTICES = MAX_SPRITES * VERTICES_PER_SPRITE;
    static constexpr size_t MAX_INDICES = MAX_SPRITES * INDICES_PER_SPRITE;

    SpriteBatch();
    ~SpriteBatch() = default;

    // 开始批次
    void begin(const glm::mat4& viewProjection);
    
    // 结束批次 - 返回需要绘制的批次列表
    void end();

    // 绘制单个精灵
    void draw(const SpriteData& sprite);
    
    // 批量绘制 - 一次性处理多个精灵
    void drawBatch(const std::vector<SpriteData>& sprites);
    
    // 立即绘制 - 不缓存，直接提交
    void drawImmediate(const SpriteData& sprite);

    // 获取当前批次数据
    const std::vector<SpriteVertex>& getVertices() const { return vertices_; }
    const std::vector<uint16_t>& getIndices() const { return indices_; }
    size_t getSpriteCount() const { return spriteCount_; }
    
    // 检查是否需要刷新
    bool needsFlush() const { return spriteCount_ >= MAX_SPRITES; }
    
    // 清空批次
    void clear();

private:
    // 三角函数查表
    TrigLookup trigLookup_;
    
    // 顶点数据 - 使用固定大小数组避免动态分配
    std::vector<SpriteVertex> vertices_;
    std::vector<uint16_t> indices_;
    size_t spriteCount_;
    
    // 变换矩阵
    glm::mat4 viewProjection_;
    glm::mat4 cachedVP_;
    bool vpDirty_;
    
    // 生成索引
    void generateIndices();
    
    // 生成顶点
    void generateVertices(const SpriteData& sprite, size_t vertexOffset);
    
    // 刷新批次
    void flush();
};

} // namespace extra2d
