#pragma once

#include <extra2d/core/color.h>
#include <extra2d/core/types.h>
#include <cstdint>

namespace extra2d {

// ============================================================================
// 混合模式枚举
// ============================================================================
enum class BlendMode {
    None,       // 不混合
    Alpha,      // 标准 Alpha 混合
    Additive,   // 加法混合
    Multiply    // 乘法混合
};

// ============================================================================
// 深度测试函数枚举
// ============================================================================
enum class DepthFunc {
    Never,      // 永不通过
    Less,       // 小于
    Equal,      // 等于
    LessEqual,  // 小于等于
    Greater,    // 大于
    NotEqual,   // 不等于
    GreaterEqual,// 大于等于
    Always      // 总是通过
};

// ============================================================================
// 裁剪模式枚举
// ============================================================================
enum class CullMode {
    None,       // 不裁剪
    Front,      // 裁剪正面
    Back,       // 裁剪背面
    Both        // 裁剪双面
};

// ============================================================================
// 顶点属性格式枚举
// ============================================================================
enum class VertexFormat {
    Float1,     // 1个float
    Float2,     // 2个float
    Float3,     // 3个float
    Float4,     // 4个float
    Byte4,      // 4个byte
    UByte4,     // 4个ubyte
    Short2,     // 2个short
    Short4      // 4个short
};

// ============================================================================
// 顶点属性描述
// ============================================================================
struct VertexAttribute {
    uint32_t location = 0;      // 属性位置
    VertexFormat format = VertexFormat::Float3;  // 数据格式
    uint32_t offset = 0;        // 在顶点结构中的偏移
    uint32_t stride = 0;        // 顶点结构大小
    bool normalized = false;    // 是否归一化

    VertexAttribute() = default;
    VertexAttribute(uint32_t loc, VertexFormat fmt, uint32_t off, uint32_t str, bool norm = false)
        : location(loc), format(fmt), offset(off), stride(str), normalized(norm) {}
};

// ============================================================================
// 管线描述结构
// ============================================================================
struct PipelineDesc {
    // 混合状态
    BlendMode blendMode = BlendMode::Alpha;
    bool blendEnabled = true;

    // 深度状态
    bool depthTest = false;
    bool depthWrite = false;
    DepthFunc depthFunc = DepthFunc::Less;

    // 裁剪状态
    CullMode cullMode = CullMode::None;

    // 顶点布局
    std::vector<VertexAttribute> vertexAttributes;

    // 着色器（由后端特定实现设置）
    void* vertexShader = nullptr;
    void* fragmentShader = nullptr;
};

// ============================================================================
// 渲染管线抽象接口 - 渲染后端无关
// ============================================================================
class Pipeline {
public:
    virtual ~Pipeline() = default;

    /**
     * @brief 绑定管线
     */
    virtual void bind() = 0;

    /**
     * @brief 解绑管线
     */
    virtual void unbind() = 0;

    /**
     * @brief 设置混合模式
     * @param mode 混合模式
     */
    virtual void setBlendMode(BlendMode mode) = 0;

    /**
     * @brief 获取当前混合模式
     * @return 混合模式
     */
    virtual BlendMode getBlendMode() const = 0;

    /**
     * @brief 设置深度测试
     * @param enabled 是否启用
     */
    virtual void setDepthTest(bool enabled) = 0;

    /**
     * @brief 设置深度写入
     * @param enabled 是否启用
     */
    virtual void setDepthWrite(bool enabled) = 0;

    /**
     * @brief 设置深度测试函数
     * @param func 深度测试函数
     */
    virtual void setDepthFunc(DepthFunc func) = 0;

    /**
     * @brief 设置裁剪模式
     * @param mode 裁剪模式
     */
    virtual void setCullMode(CullMode mode) = 0;

    /**
     * @brief 检查管线是否有效
     * @return 有效返回 true
     */
    virtual bool isValid() const = 0;

    /**
     * @brief 获取原生句柄（后端特定）
     * @return 原生句柄值
     */
    virtual uintptr_t getNativeHandle() const = 0;
};

} // namespace extra2d
