#pragma once

#include <extra2d/core/color.h>
#include <extra2d/core/types.h>
#include <glm/mat4x4.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <string>
#include <vector>

namespace extra2d {

// ============================================================================
// 着色器类型枚举
// ============================================================================
enum class ShaderType {
    Vertex,     // 顶点着色器
    Fragment,   // 片段着色器
    Geometry,   // 几何着色器
    Compute     // 计算着色器
};

// ============================================================================
// 着色器描述结构
// ============================================================================
struct ShaderDesc {
    std::string name;           // 着色器名称
    std::string vertexSource;   // 顶点着色器源码
    std::string fragmentSource; // 片段着色器源码
    std::string geometrySource; // 几何着色器源码（可选）
    std::vector<uint8_t> binaryData; // 预编译二进制数据（可选）
};

// ============================================================================
// 着色器抽象接口 - 渲染后端无关
// ============================================================================
class Shader {
public:
    virtual ~Shader() = default;

    /**
     * @brief 绑定着色器程序
     */
    virtual void bind() = 0;

    /**
     * @brief 解绑着色器程序
     */
    virtual void unbind() = 0;

    /**
     * @brief 设置布尔类型 uniform 变量
     * @param name uniform 变量名
     * @param value 布尔值
     */
    virtual void setBool(const std::string& name, bool value) = 0;

    /**
     * @brief 设置整数类型 uniform 变量
     * @param name uniform 变量名
     * @param value 整数值
     */
    virtual void setInt(const std::string& name, int value) = 0;

    /**
     * @brief 设置浮点类型 uniform 变量
     * @param name uniform 变量名
     * @param value 浮点值
     */
    virtual void setFloat(const std::string& name, float value) = 0;

    /**
     * @brief 设置二维向量类型 uniform 变量
     * @param name uniform 变量名
     * @param value 二维向量值
     */
    virtual void setVec2(const std::string& name, const glm::vec2& value) = 0;

    /**
     * @brief 设置三维向量类型 uniform 变量
     * @param name uniform 变量名
     * @param value 三维向量值
     */
    virtual void setVec3(const std::string& name, const glm::vec3& value) = 0;

    /**
     * @brief 设置四维向量类型 uniform 变量
     * @param name uniform 变量名
     * @param value 四维向量值
     */
    virtual void setVec4(const std::string& name, const glm::vec4& value) = 0;

    /**
     * @brief 设置 4x4 矩阵类型 uniform 变量
     * @param name uniform 变量名
     * @param value 4x4 矩阵值
     */
    virtual void setMat4(const std::string& name, const glm::mat4& value) = 0;

    /**
     * @brief 设置颜色类型 uniform 变量
     * @param name uniform 变量名
     * @param color 颜色值
     */
    virtual void setColor(const std::string& name, const Color& color) = 0;

    /**
     * @brief 设置纹理采样器
     * @param name uniform 变量名
     * @param slot 纹理槽位
     */
    virtual void setTexture(const std::string& name, int slot) = 0;

    /**
     * @brief 获取着色器名称
     * @return 着色器名称
     */
    virtual const std::string& getName() const = 0;

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

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

} // namespace extra2d
