#pragma once

#include <SDL3/SDL.h>
#include <string>
#include "../../core/interfaces/IRenderer.h"

/**
 * RenderManager - Abstracts SDL rendering functionality
 * 
 * Responsibilities:
 * - Manage SDL_Window and SDL_Renderer lifecycle
 * - Provide high-level rendering interface
 * - Handle viewport and scaling logic
 * - Abstract SDL-specific details from game code
 */
class RenderManager : public IRenderer {
public:
    RenderManager();
    ~RenderManager();

    // Initialization and cleanup
    bool initialize(int width, int height, const std::string& title);
    void shutdown();

    // Frame management
    void beginFrame();
    void endFrame();

    // IRenderer interface implementation
    void clearScreen(uint8_t r, uint8_t g, uint8_t b, uint8_t a) override;
    void present() override;
    SDL_Renderer* getSDLRenderer() override;
    void getWindowDimensions(int& width, int& height) const override;
    void setViewport(const SDL_Rect* viewport) override;
    void setScale(float scaleX, float scaleY) override;

    // Additional RenderManager-specific methods
    void setLogicalSize(int width, int height);
    void setViewport(int x, int y, int width, int height);
    void resetViewport();

    // Query the computed logical viewport and scale (useful for consistent input mapping)
    SDL_Rect getLogicalViewport() const { return m_logicalVP; }
    float getLogicalScale() const { return m_logicalScale; }

    // Basic rendering operations (legacy method signature)
    void clear(Uint8 r = 0, Uint8 g = 0, Uint8 b = 0, Uint8 a = 255);
    
    // Texture rendering
    void renderTexture(SDL_Texture* texture, const SDL_FRect* src, const SDL_FRect* dst);
    void renderTexture(SDL_Texture* texture, float x, float y);
    void renderTexture(SDL_Texture* texture, float x, float y, float w, float h);

    // Primitive rendering
    void renderRect(const SDL_FRect& rect, Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255);
    void renderLine(float x1, float y1, float x2, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255);
    void renderPoint(float x, float y, Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255);

    // Window management
    void handleWindowResize(int newWidth, int newHeight);
    void setFullscreen(bool fullscreen);
    void getWindowSize(int& width, int& height) const;

    // Direct access to SDL objects (temporary, will be removed later)
    SDL_Window* getSDLWindow() const { return m_window; }
    // Texture queries
    void getTextureSize(SDL_Texture* tex, int& w, int& h) const;

    // State queries
    bool isInitialized() const { return m_initialized; }
    bool isFullscreen() const { return m_isFullscreen; }

private:
    // SDL objects
    SDL_Window* m_window = nullptr;
    SDL_Renderer* m_renderer = nullptr;

    // Window properties
    int m_windowWidth = 0;
    int m_windowHeight = 0;
    int m_logicalWidth = 0;
    int m_logicalHeight = 0;
    float m_scaleX = 1.0f;
    float m_scaleY = 1.0f;
    
    // State
    bool m_initialized = false;
    bool m_isFullscreen = false;
    // Cached logical viewport and scale (centered within window)
    SDL_Rect m_logicalVP{0,0,0,0};
    float m_logicalScale = 1.0f;
    
    // Helper methods
    void updateLogicalScale();
};
