// File: src/Renderer.h
#pragma once

#include "glm/glm.hpp"
#include "systems/Shader.h"
#include <gl/glew.h>
#include "types/vec2.h"
namespace OX {

    struct Sprite {
        GLuint        textureID;
        glm::vec2     position;
        glm::vec2     size;
    };

    class Camera2D {
    public:
        Camera2D(float left, float right, float bottom, float top);
        void SetPosition(const glm::vec2& pos);
        void SetZoom(float zoom);
        const glm::mat4& GetViewProjection() const;

    private:
        void Recalculate();
        glm::vec2 _position{0.0f};
        float     _zoom{1.0f};
        float     _left, _right, _bottom, _top;
        glm::mat4 _viewProj{1.0f};
    };

    class Renderer {
    public:
        Renderer() = default;
        ~Renderer();

        /// Must call once after OpenGL context + GLEW init.
        /// Provide the desired offscreen target size here.
        void Init(int targetWidth, int targetHeight);

        /// Call at start of each scene (binds FBO and sets camera).
        void BeginScene(const Camera2D& camera);

        /// Draw one sprite into the current scene.
        void DrawSprite(const Sprite& sprite);

        /// Finish rendering, unbinds FBO.
        void EndScene();

        /// Access the color‐attachment texture ID that holds the rendered scene.
        GLuint GetRenderTexture() const { return m_colorTex; }

        /// If window resized, call this to resize the offscreen target.
        void ResizeTarget(int width, int height);

    private:
        // offscreen
        Vec2i size;
        GLuint m_fbo         = 0;
        GLuint m_colorTex    = 0;
        GLuint m_depthRBO    = 0;

        // quad geometry
        GLuint m_quadVAO     = 0, m_quadVBO = 0;

        // shader
        Shader m_shader;
        glm::mat4 m_viewProj{1.0f};

        // helpers
        void CreateQuad();
        void CreateFramebuffer(int width, int height);
    };

} // namespace OX
