#pragma once
#include <glm/glm.hpp>
#include <string>  
#include "glad.h"

// Modern renderer using C++23 features
class Renderer {
public:
    // Render states using scoped enum
    enum class CullFace : GLenum {
        None = 0,
        Front = GL_FRONT,
        Back = GL_BACK,
        FrontAndBack = GL_FRONT_AND_BACK
    };

    enum class BlendMode : int {
        None = 0,
        Alpha,
        Additive,
        Multiply
    };

    enum class DepthTest : int {
        None = 0,
        Less,
        LessEqual,
        Greater,
        GreaterEqual,
        Equal,
        NotEqual,
        Always,
        Never
    };

    struct RenderStats {
        size_t draw_calls = 0;
        size_t vertices_rendered = 0;
        size_t triangles_rendered = 0;
        float frame_time = 0.0f;
    };

    Renderer();
    ~Renderer() = default;

    // Delete copy constructor and assignment
    Renderer(const Renderer&) = delete;
    Renderer& operator=(const Renderer&) = delete;

    void Initialize();
    void Shutdown();

    // Frame management
    void BeginFrame();
    void EndFrame();
    
    void Clear(const glm::vec4& color = {0.0f, 0.0f, 0.0f, 1.0f});
    void SetViewport(int x, int y, int width, int height);
    
    // Render state management
    void SetCullFace(CullFace cull_face);
    void SetBlendMode(BlendMode blend_mode);
    void SetDepthTest(DepthTest depth_test);
    void SetWireframe(bool enable);

    // Modern getters using [[nodiscard]]
    [[nodiscard]] const RenderStats& GetStats() const { return stats_; }
    [[nodiscard]] glm::ivec2 GetViewportSize() const { return viewport_size_; }
    [[nodiscard]] bool IsWireframeEnabled() const { return wireframe_enabled_; }

    // Debug functions
    void PrintRenderInfo() const;
    void ResetStats();

    // Utility functions
    [[nodiscard]] static std::string GetOpenGLVersion();
    [[nodiscard]] static std::string GetGPUInfo();
    [[nodiscard]] static bool CheckOpenGLError(const std::string& operation = "");

private:
    RenderStats stats_;
    glm::ivec2 viewport_size_{0, 0};
    
    // Current render states
    CullFace current_cull_face_ = CullFace::Back;
    BlendMode current_blend_mode_ = BlendMode::None;
    DepthTest current_depth_test_ = DepthTest::Less;
    bool wireframe_enabled_ = false;

    // Performance tracking
    float frame_start_time_ = 0.0f;

    void SetOpenGLState();
    void UpdateStats();
    [[nodiscard]] float GetTime() const;
};