#pragma once

#include <SDL3/SDL.h>

#include "rendering/shader_backend.hpp"

namespace Rendering {

    class Sdl3GpuShaderBackend final : public IShaderBackend {
       public:
        Sdl3GpuShaderBackend() = default;
        ~Sdl3GpuShaderBackend() override;

        auto init(SDL_Window* window) -> bool override;
        auto loadShader(const ShaderProgramSpec& spec) -> bool override;
        void render(const ShaderUniforms& uniforms) override;
        void setVSync(bool vsync) override;
        void cleanup() override;
        [[nodiscard]] auto driverName() const -> std::string override { return driver_name_; }

       private:
        struct UniformsStd140 {
            float iTime{0.0f};
            float pad0{0.0f};
            float iResolutionX{0.0f};
            float iResolutionY{0.0f};
        };

        auto createDevice() -> bool;
        auto loadVertexShaderFor(const ShaderProgramSpec& spec) -> bool;
        auto buildPipeline(SDL_GPUShader* fragment) -> SDL_GPUGraphicsPipeline*;
        [[nodiscard]] auto bestPresentMode() const -> SDL_GPUPresentMode;

        SDL_Window* window_{nullptr};
        SDL_GPUDevice* device_{nullptr};
        SDL_GPUShader* vertex_shader_{nullptr};
        SDL_GPUShader* fragment_shader_{nullptr};
        SDL_GPUGraphicsPipeline* pipeline_{nullptr};

        bool vsync_{true};
        std::string driver_name_;
    };

}  // namespace Rendering
